博弈论
I.I和.I.可以将n个块分为俩部分,.I.相邻的俩个块还应该判断一下,如果是III,则还可以使用一次,即ANS=(ANS^1),否则不能使用,
分为几部分之后,对于每一个部分的sg值异或起来就是答案。
sg[cnt][now]中cnt指块的长度,now指块的二进制表示,III用1表示,II.或者.II用0表示,然后预处理sg值,具体方法看代码
#include<stdio.h>
#include<string.h>
int sg[25][(1<<21)];
int er[25];
int a[25],b[25],flag[25],vis[55];
void getsg(){
er[0]=1;
for(int i=1;i<=24;i++)er[i]=er[i-1]*2;
sg[1][0]=1;
sg[1][1]=2;
for(int i=2;i<=20;i++){
for(int n=0;n<=er[i]-1;n++){
memset(vis,0,sizeof(vis));
for(int k=1;k<=i;k++){
b[k]=((n&er[k-1])!=0);
/*if(i==7&&n==29){
printf("b[%d]=%d\n",k,b[k]);
}*/
}
for(int k=1;k<=i;k++){
if(b[k]==1){
int t=0;
if(k==1){
t=sg[i-1][n>>1];
}
else if(k==i){
t=sg[i-1][n-er[k-1]];
}
else{
t=sg[k-1][n&(er[k-1]-1)]^sg[i-k][n>>k];
}
if(t<50)vis[t]=1;
if(sg[i][n-er[k-1]]<50)
vis[sg[i][n-er[k-1]]]=1;
}
else{
int t=0;
if(k>2){
t=(t^sg[k-2][n&(er[k-2]-1)]^b[k-1]);
if(k==i-1){
t=(t^b[i]);
}
if(k<=i-2){
t=(t^b[k+1]^sg[i-k-1][n>>(k+1)]);
}
}
else if(k==2){
t=(t^b[1]);
if(k==i-1){
t=(t^b[i]);
}
if(k<=i-2){
t=(t^b[k+1]^sg[i-k-1][n>>(k+1)]);
}
}
else if(k==1){
if(k==i-1){
t=(t^b[i]);
}
if(k<=i-2){
t=(t^b[k+1]^sg[i-k-1][n>>(k+1)]);
}
}
if(t<50)
vis[t]=1;
}
}
int ans=0;
while(vis[ans]!=0)ans++;
//printf("000\n");
sg[i][n]=ans;
}
}
}
char s[10];
int main(){
//printf("%d\n",(1<<21));
getsg();
/*for(int i=1;i<=10;i++){
for(int j=0;j<=er[i]-1;j++){
printf("sg[%d][%d]=%d\n",i,j,sg[i][j]);
}
}*/
int t;
scanf("%d",&t);
while(t--){
memset(flag,0,sizeof(flag));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%s",s+1);
if(s[1]==‘I‘&&s[2]==‘I‘&&s[3]==‘I‘)a[i]=3;
else if(s[1]==‘.‘&&s[2]==‘I‘&&s[3]==‘.‘)a[i]=0;
else if(s[1]==‘I‘&&s[2]==‘.‘&&s[3]==‘I‘)a[i]=1;
else a[i]=2;
}
for(int i=1;i<=n;i++){
if(a[i]==0){
flag[i]=1;
if(i>1)
flag[i-1]=1;
if(i<n)
flag[i+1]=1;
}
if(a[i]==1)flag[i]=1;
}
int ans=0;
int cnt=0,now=0;
for(int i=1;i<=n;i++){
if(flag[i]==1&&a[i]==3){
ans=(ans^1);
}
if(flag[i]==0){
now=now*2+((a[i]-2));
cnt++;
}
else{
ans=(ans^sg[cnt][now]);
cnt=0;
now=0;
}
}
//printf("cnt=%d now=%d\n",cnt,now);
ans=(ans^sg[cnt][now]);
if(ans==0){
printf("Second\n");
}
else{
printf("First\n");
}
}
}
Radewoosh+mnbvmar Contest (supported by AIM Tech)
原文:https://www.cnblogs.com/League-of-cryer/p/14110151.html