1. 程式人生 > >2018 青島區域賽 C - Flippy Sequence

2018 青島區域賽 C - Flippy Sequence

                                            Flippy Sequence

Sample Input

3
1
1
0
2
00
11
5
01010
00111

Sample Output

0
2
6

Hint

For the second sample test case, there are two valid operation pairs: (1, 1, 2, 2) and (2, 2, 1, 1).

For the third sample test case, there are six valid operation pairs: (2, 3, 5, 5), (5, 5, 2, 3), (2, 5, 4, 4), (4, 4, 2, 5), (2, 4, 4, 5) and (4, 5, 2, 4).

 題意描述:

給出兩個長度為n的01串,通過一種變化,每次可將一個連續區間裡的0變為1,1變為0。求若經過兩次這種變化,使得兩個01串完全相同共有多少中方法。

解題思路:

將兩個01串通過按位異或,得到一個新的01串,0代表此位置兩個01串相同,1代表此位置兩個01串不同。通過按位異或得到的01串其中0可經過兩次變化還為0,即此位置還是相同的,1可經過一次變化,此位置變為相同。通過找規律可知,因求的是經過兩次變化01串相同的方法,若1被分為三段或三段以上則經過兩次無法實現使得兩個01串相同。若1被分為兩段,可知共有6種方法;當1只有一段且含有0段時,共有(n-1)*2種方法;當全為0時共有(n+1)*n/2方法;當全為1時共有(n-1)*2種方法。

程式程式碼:

#include<stdio.h>
#define N 1000020
char a[N],b[N];
int c[N];
int main()
{
	long long t,n,i,sum,temp;
	scanf("%lld",&t);
	while(t--)
	{
		sum=0;
		scanf("%lld",&n);
		scanf("%s %s",a,b);
		for(i=0;i<n;i++)
		{
			c[i]=(a[i]-'0')^(b[i]-'0');
			sum+=c[i];
		}
		if(sum==n)
		{
			printf("%lld\n",(n-1)*2);
			continue;
		}
		if(sum==0)
		{
			printf("%lld\n",n*(n+1)/2);
			continue;
		}
		temp=0;
		if(c[0]==1)
			temp++;
		for(i=1;i<n;i++)
		{
			if(c[i]==1&&c[i-1]!=1)
				temp++;
			if(temp>2)
				break;
		}
		if(temp>2)
		{
			printf("0\n");
			continue;
		}
		if(temp==1)
		{
			printf("%lld\n",(n-1)*2);     
		}
		else if(temp==2)
		{
			printf("6\n");
		}
	}
	return 0;
}