51nod 2533 最优填充

题目链接:http://class.51nod.com/Course/Problem.html#courseProblemId=1315&classId=59

一、题目描述

字符串s只包含两种字符A,B,已知它某些位上的字符,你想要把它填充完整使得相邻字母相同的次数尽量少,问这个最少次数。

输入

第一行两个数n,m,表示字符串长度,已知位置数。
第二行m个数pos[i];
第三行一个长度为m的字符串val[i],表示s[pos[i]]=val[i]。
保证pos[i]两两不同。
n<=10^9,m<=50,1<=pos[i]<=n,val[i]='A'or'B'。

输出

一个数,表示最少次数。

输入样例

3 2
1 3
AB

输出样例

1

二、思路描述

我们把输入的字符串想成一个含空格的字符串:

A _ _ B

先确定左右两边的字母是相同还是不相同
(一)如果相同
那么要看两个字母中间的空格数量是奇数还是偶数
1、奇数
相邻的两个字母不会是相同的字母 -> 不判断了
2、偶数
相邻的两个字母有可能是相同的字母,答案+1
(二)如果不同
那么要看两个字母中间的空格数量是奇数还是偶数 -> 不判断了
1、奇数
相邻的两个字母有可能是相同的字母,答案+1
2、偶数
相邻的两个字母不会是相同的字母

三、代码

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;


struct node{
    int pos;//pos为这个数的下标 
    char x;//x为这个数字是A还是B 
}a[51];

bool cmp(node x, node y){
    return x.pos < y.pos;//按照下标从大到小进行排序 
}

int main(){
    int n, m, ans = 0; 
    char s[100];
    cin >> n >> m;
    for(int i = 1; i <= m; i++){
        cin >> a[i].pos;
    }
    cin >> s+1;
    for(int i = 1; i <= m; i++){
        a[i].x = s[i];
    }
    sort(a+1, a+1+m, cmp);//按照下标从大到小排序 
    if(m == 1){
        cout << '0' << endl;//如果你只知道1个字母 
    }else {
        for(int i = 2; i <= m; i++){
            int tmp = a[i].pos - a[i-1].pos;//两个字母之间的空格数量 
            if((tmp&1) && (a[i].x == a[i-1].x)){//如果tmp是奇数并且两头的字母相等 
                ans++;//次数+1 
            }
            if(!(tmp&1) && (a[i].x != a[i-1].x)){//如果tmp是偶数并且两头的字母不相等 
                ans++;//次数+1 
            }
        }
        cout << ans << endl;//输出次数 
    }
    return 0; 
}
原文地址:https://www.cnblogs.com/elisa02/p/12778631.html