Daizhenyang's Coin (sg函数)
题意:有1e8硬币,其中有n个是正面朝上的,每步可以取1或3个硬币翻转,且所选最右边的硬币必须正面朝上,谁先不能动谁输。
题解:分布考虑,若每次可以选择1个硬币翻转,相当于nim游戏把一堆石子取完,2个硬币翻转(a位置与b位置,a>b),相当于把一堆大小为a的石子取到b,于是可想到3个硬币翻转相当于一堆石子变成两堆小石子,即可以从sg[b]^sg[c]转移,故可以枚举sg函数打表,发现其sg[i]=i*2+(i的2进制是否存在奇数个1)1;
#include<iostream>
using namespace std;
int n,a[1007][1007];
int b[1007][1007];
int c[1007][1007];
char s[1007][1007];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>s[i]+1;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j]=s[i][j]-'0';
b[i][j]=c[i][j]=a[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=2;j<=n;j++){
if(a[i][j]!=0){
b[i][j]+=b[i][j-1];
}
if(a[j][i]!=0){
c[j][i]+=c[j-1][i];
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d ",b[i][j]);
}puts("");
}puts("");
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
printf("%d ",c[i][j]);
}puts("");
}puts("");
}