2018青岛区域赛C:Flippy Sequence

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41505957/article/details/83930384

 

 题意:找出l,r在此区域内的所有数0变为1,1变为0,进行两次操作,问一共有多少种方法。

两个串相同就是两个串的异或值为0

把两个串异或,

找出连续的1的有多少块。

1.两块以上的无法用两次操作达到效果,所以为0

2.全为1的有(n-1)*2种,因为要把所有的1变成0,所以只要把串分为两部分,明显有(1,1,2, n)(1,2,3,n-2).....

(1,n-1,n,n),一共n-1种,反过来又有n-1种。

3.全为0的需要把一段串改变两次,选一个有n种,选两个有n-1种......选n个有一种,因为是相同的,所以不能反过来。有n(n+1)/2。

4.有两块连续的1的情况,一共只有6种情况,两块1分两次改变为一次,左边连续的1和中间的0改变一次再把右边连续的1和中间的0改变一次,   改变从左到右连续的一和中间的0再改变中间的0,一共3次,反过来为6次。

#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(n==1&&c[0]==0)
		{
			printf("1\n");
			continue;
		}
		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;
}

猜你喜欢

转载自blog.csdn.net/qq_41505957/article/details/83930384