码迷,mamicode.com
首页 > 其他好文 > 详细

UVa10561 Treblecross

时间:2017-01-14 07:27:17      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:处理   namespace   bsp   clu   win   pre   inline   name   ring   

博弈 sg函数

 

如果能一步取胜的话,直接扫一遍,找出所有能一步取胜的位置输出。

否则枚举放‘X’的位置,计算剩下空区间的SG函数的异或和,若为0,则该位置可以作为答案。

计算空区间时要刨去X旁边的两个空(放在这里必败) 例如.X.....X.这一区段的可用长度为3

SG函数的预处理还不太理解


↓那个pd()并没有用到

  1 /*by SilverN*/
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 using namespace std;
  8 const int mxn=210;
  9 char s[mxn];
 10 int n,f[mxn];
 11 inline bool pd(){
 12     for(int i=2;i<n;i++){
 13         if(s[i-1]==X && s[i]==X && s[i+1]==X)return 1;
 14     }
 15     return 0;
 16 }
 17 inline bool check(int pos){
 18     if(s[pos+1]==X){
 19         if(s[pos-1]==X || s[pos+2]==X)return 1;
 20     }
 21     else if(s[pos-1]==X){
 22         if(pos>2 && s[pos-2]==X)return 1;
 23     }
 24     return 0;
 25 }
 26 inline bool ar(int p){
 27     for(int i=max(1,p-2);i<=p+2;i++)if(s[i]==X)return 1;
 28     return 0;
 29 }
 30 bool calc(){
 31     int i,j,len=0;
 32     int res=0;
 33     for(i=1;i<=n;i++){
 34         if(ar(i)){
 35             res^=f[len]; len=0;
 36         }
 37         else len++;
 38     }
 39     res^=f[len];
 40     return res;
 41 }
 42 int ans[mxn],cnt=0;
 43 void solve(){
 44     cnt=0;
 45     int i,j;
 46     for(i=1;i<=n;i++){
 47         if(s[i]!=.)continue;
 48         if(check(i)){
 49             for(j=i;j<=n;j++)
 50                 if(s[j]==. && check(j)){ans[++cnt]=j;}
 51             return;
 52         }
 53     }
 54     if(calc()){
 55         for(i=1;i<=n;i++){
 56             if(!ar(i)){
 57                 s[i]=X;
 58                 if(!calc()){
 59                     ans[++cnt]=i;
 60                 }
 61                 s[i]=.;
 62             }
 63         }
 64     }
 65     return;
 66 }
 67 int vis[mxn];
 68 void init(){//处理sg函数 
 69     int i,j,x;
 70     f[1]=f[2]=1;
 71     for(i=3;i<mxn;i++){
 72         memset(vis,0,sizeof vis);
 73         for(j=1;j*2<=i+1;j++){
 74             x=f[i-j-2];//去掉边界两个空位 
 75             if(j>3)x^=f[j-3];
 76             vis[x]=1;
 77         }
 78         for(j=0;;j++){if(!vis[j]){f[i]=j;break;}}
 79     }
 80     return;
 81 }
 82 int main(){
 83     int T;scanf("%d",&T);
 84     init();
 85     while(T--){
 86         memset(s,0,sizeof s);
 87         scanf("%s",s+1);
 88         n=strlen(s+1);
 89         solve();
 90         if(cnt){
 91             printf("WINNING\n");
 92             for(int i=1;i<cnt;i++){
 93                 printf("%d ",ans[i]);
 94             }
 95             printf("%d\n",ans[cnt]);
 96         }
 97         else printf("LOSING\n\n");
 98     }
 99     return 0;
100 }

 

UVa10561 Treblecross

标签:处理   namespace   bsp   clu   win   pre   inline   name   ring   

原文地址:http://www.cnblogs.com/SilverNebula/p/6284497.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!