Developing School's Contest 2012-2 by HUT :DNA-AND-DNA

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


你可能感兴趣的:(Developing School's Contest 2012-2 by HUT :DNA-AND-DNA)