Daizhenyang's Coin (sg函数)

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("");
}

posted @ 2020-10-26 19:18  ccsu_madoka  阅读(87)  评论(0编辑  收藏  举报