ZOJ 4060 Flippy Sequence(思维)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4060

题目大意:有两个只包含0和1字符串,,通过将字符串1区间内的0和1反转2次(0反转为1,1反转为0),求方案数。

思路:反转的顺序不会影响最后的结果。为了方便分析,我将所有的字符串2都看作是0组成的,字符串1内的1就是需要我们反转的,分析以下情况。

(1)字符串全为1,例如:1,11,111,1111。其对应的方案数为,0,2,4,6.。ans=(n-1)*2;

(2)字符串全为0,例如:0,00,000,0000。其对应的方案数为,1,3,6,10.。ans=(n+1)*n./2;

(3)0001100类型,l表示左边0的个数,mid表示中间0的个数,r表示右边0的个数。ans=(mid-1)*2+(l+r)*2;

(4)000110011000类型,恰好两对连续的1,ans=6;

(5)000110011011,00110011011011011...类型,出现了3个及以上的连续的1,我们无法通过反转2次得到答案,ans=0;

AC代码:

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

const int MAXN = 1e6+10;
char str1[MAXN];
char str2[MAXN];
typedef long long ll;
int main(){
	//freopen("in.txt","r",stdin);
	int T;scanf("%d",&T);
	while(T--){
		int n;scanf("%d",&n);
		scanf("%s%s",str1,str2);
		int flag=0;
		int sameCnt=0,diffCnt=0;
		queue<int> aSame,aDiff;
		while(!aSame.empty()) aSame.pop();
		while(!aDiff.empty()) aDiff.pop();
		//flag=1表示正在计数连续相同的字符串长度
		//flag=2表示正在计数连续不相同的字符串长度
		for(int i=0;i<n;i++){
			if(str1[i]==str2[i]){
				if(flag==1){
					sameCnt++;
				}else if(flag==2){
					aDiff.push(diffCnt);
					diffCnt=0;
					sameCnt=1;
					flag=1;
				}else{
					sameCnt++;
					flag=1;
				}
			}else{
				if(flag==2){
					diffCnt++;
				}else if(flag==1){
					aSame.push(sameCnt);
					sameCnt=0;
					diffCnt=1;
					flag=2;
				}else{
					diffCnt++;
					flag=2;
				}
			}
		}
		if(sameCnt) aSame.push(sameCnt);
		if(diffCnt) aDiff.push(diffCnt);
		ll ans=0;
		if(aSame.size()==1&&aDiff.size()==0){
			ans=(n+1)*n/2;
			printf("%lld\n",ans);
			continue;
		}
		if(aDiff.size()>2){
			printf("0\n");
			continue;
		}
		bool firstSame=0;
		if(str1[0]==str2[0])
			firstSame=1;
	
		int l,r,mid;
		if(firstSame){
			if(aDiff.size()==1){
				l=0;r=0;mid=0;
				mid=aDiff.front();aDiff.pop();
				l=aSame.front();aSame.pop();
				if(aSame.empty())
					ans=(mid-1)*2+l*2;
				else{
					r=aSame.front();aSame.pop();
					ans=(mid-1)*2+(l+r)*2;
				}
			}else{
				ans=6;
			}
		}else{
			if(aDiff.size()==1){
				l=0;r=0;mid=0;
				l=aDiff.front();aDiff.pop();
				if(!aSame.empty()){
					mid=aSame.front();
					aSame.pop();
				}
				ans=(l-1)*2+mid*2;
			}else{
				ans=6;
			}
		}
		printf("%lld\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Rainbow_storm/article/details/83961806