山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

UVA 10561 Treblecross(博弈论)

 

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32209

 

【思路】

       博弈论。

       根据X分布划分禁区,每个可以放置的块为单独一个游戏。按长度定义状态,构造sg函数。依次试验每一种放法。

 

【代码】

 

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int N = 200+10;
 8 
 9 int g[N],n;
10 
11 int mex(vector<int>& s) {
12     if(s.empty()) return 0;
13     sort(s.begin(),s.end());
14     if(s[0]) return 0;
15     for(int i=1;i<s.size();i++)
16         if(s[i]>s[i-1]+1) return s[i-1]+1;
17     return s[s.size()-1]+1;
18 }
19 void get_g() {
20     g[0]=0; g[1]=g[2]=g[3]=1;
21     for(int i=4;i<=N-10;i++) {
22         vector<int> s;
23         s.push_back(g[i-3]);
24         s.push_back(g[i-4]);
25         if(i>=5) s.push_back(g[i-5]);
26         for(int j=3;j<i-3;j++)
27             s.push_back(g[j-2] ^ g[i-j-3]);
28         g[i]=mex(s);
29     }
30 }
31 
32 bool winning(char *s) {
33     int n=strlen(s);
34     for(int i=0;i<n-2;i++) 
35         if(s[i]=='X' && s[i+1]=='X' && s[i+2]=='X') return false;
36     int no[N];
37     memset(no,0,sizeof(no));
38     no[n]=1;
39     for(int i=0;i<n;i++) if(s[i]=='X') {
40         for(int d=-2;d<=2;d++)
41             if(i+d>=0 && i+d<n) {
42                 if(d!=0 && s[i+d]=='X') return true;
43                 no[i+d]=1;
44             }
45     }
46     
47     int sg=0;
48     int start=-1;
49     for(int i=0;i<=n;i++) {
50         if(start<0 && !no[i]) start=i;
51         if(no[i] && start>=0) sg^=g[i-start];
52         if(no[i]) start=-1;
53     }
54     return sg!=0;
55 }
56 
57 int main() {
58     get_g();
59     int T; scanf("%d",&T);
60     while(T--) {
61         char s[N];
62         scanf("%s",s);
63         int n=strlen(s);
64         if(!winning(s)) puts("LOSING\n");
65         else {
66             puts("WINNING");
67             bool first=1;
68             for(int i=0;i<n;i++) if(s[i]=='.') {
69                 s[i]='X';
70                 if(!winning(s))
71                     if(first) printf("%d",i+1) , first=0;
72                     else printf(" %d",i+1);
73                  s[i]='.';
74             }
75             putchar('\n');
76         }
77     }
78     return 0;
79 }

 

posted on 2016-01-28 20:37  hahalidaxin  阅读(279)  评论(0编辑  收藏  举报