[简单思维] 题解 123 Triangle

[简单思维] 题解 123 Triangle

题目链接

自己想出来的,还是挺不错的。

题目分析

进行一次操作之后剩下的数就只有 (0,1,2) 了,所以只考虑序列中的数为 (0,1,2) 的情况。

如果操作是在模 (2) 意义下进行的,那么序列中的数只能是 (0,1) ,此时两个数的差的绝对值在模 (2) 意义下就等于两个数在模 (2) 意义下的和,于是我们就可以通过组合数直接求出答案,如果答案为 (1) ,那么原本的答案就是 (1) ,否则原本的答案就有可能是 (0) 或者 (2)

考虑何时答案才有可能是 (2) ,可以发现,答案为 (2) 时序列中必然不能出现 (1) ,可以使用归纳法证明,这里就不证明了,此时序列中的所有数都是 (0,2) ,除以 (2) 后就都是 (0,1) ,于是继续用组合数直接求答案,然后就可以判断答案是否为 (2)

如果答案既不是 (1) 也不是 (2) ,那么答案就是 (0)

参考代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ch() getchar()
#define pc(x) putchar(x)
using namespace std;
template<typename T>void read(T&x){
	static char c;static int f;
	for(c=ch(),f=1;c<'0'||c>'9';c=ch())if(c=='-')f=-f;
	for(x=0;c>='0'&&c<='9';c=ch())x=x*10+(c&15);x*=f;
}
template<typename T>void write(T x){
	static char q[65];int cnt=0;
	if(x<0)pc('-'),x=-x;
	q[++cnt]=x%10,x/=10;
	while(x)
		q[++cnt]=x%10,x/=10;
	while(cnt)pc(q[cnt--]+'0');
}
const int maxn=1000005;
char s[maxn];int a[maxn];
int Abs(int x){return x<0?-x:x;}
int main(){
	int n;read(n);scanf("%s",s);
	for(int i=0;i<n;++i)a[i]=s[i]-'0';--n;
	for(int i=0;i<n;++i)a[i]=Abs(a[i]-a[i+1]);int ans=0;
	for(int i=0;i<n;++i)if((i&(n-1))==i)ans=(ans+a[i])&1;
	if(ans==1)puts("1");
	else{
		int ok=true;
		for(int i=0;i<n&&ok;++i){
			if(a[i]&1)ok=false;else a[i]=a[i]>>1;
		}
		if(ok){
			ok=0;for(int i=0;i<n;++i)if((i&(n-1))==i)ok=(ok+a[i])&1;
		}
		puts(ok?"2":"0");
	}
	return 0;
}

原文地址:https://www.cnblogs.com/lsq147/p/13928348.html