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; }