[简单思维] 题解 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;
}