Problem Description
生物学家们发现了一个奇怪的DNA分子,可以将它们看作一个由集合{A,B} 中的元素组成的N个字符的序列。由于
一系列的突变
使得DNA链只包含A。生物学家发现这很奇怪,所以他们开始研究更详细的基因突变。他们发现了两种
类型的基因突变。一种类型
是改变单个字符的序列(A→B或B→A)。第二类改变了整个序列的前缀,从1到K
(1和N之间)。计算数量尽可能少的突变,可以
是起始分子转化到它的最终状态(只包含A字符)。突变可以在任何
顺序发生。
Input
输入有多组数据。输入的第一行包含一个正整数N(1≤N≤1000 000),表示分子的长度。输入第二行包含N个字符
的字符串,
这个字符串由A或B组成,表示DNA分子的起始状态。
Output
输出的一行表示必须的最低数量的突变。
Sample Input
4 ABBA 5 BBABB 12 AAABBBAAABBB
Sample Output
2 2 4
Source
2012暑假集训
//1、当某个字符只单个存在的时候显然对它只变一次即可! 2、当某个字符相邻连续出现两个的时候,那么一个个突
变和将它按照前缀
序列翻转都只需2次,3、而当某个字符相邻连续出现3个以上的时候则肯定是按照前缀子串翻转最佳
(也是2次)则2、3规则可以合并。
所以只要从后往前扫描序列按照规则记录次数即可。同时需要记录翻转次数
(处理之前的串)用以判断当前扫描的串是否需要翻转。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
#define maxn 1000005
char str[maxn];
int main()
{
int n,i,j;
while(~scanf("%d",&n))
{
scanf("%s",str+1);
for(i=n;i>=1;i--)
if(str[i]!='A')
break;
int tp=0,ans=0,num=0;
str[i+1]='*';
for(j=i;j>=1;j--)
{
if(str[j]!=str[j+1])
{
if(str[j+1]=='B'&&!tp) //突变偶数次它仍是B
{
ans++;
if(num>1) tp=(tp+1)&1;
}
else if(str[j+1]=='A'&&tp) //突变奇数变成B,需要再变一次
{
ans++;
if(num>1) tp=(tp+1)&1;
}
num=1;
}
else num++;
}
if((str[1]=='B'&&!tp)||(str[1]=='A'&&tp))
ans++;
printf("%d\n",ans);
}
return 0;
}