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

[bzoj 1188]分裂游戏

时间:2017-09-26 16:07:13      阅读:134      评论:0      收藏:0      [点我收藏+]

标签:problem   name   http   nbsp   for   set   color   多少   scan   

题目大意:

共有n个瓶子,第i个瓶子中装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个瓶子。标号i,j,k.并要保证i<j<=k且第i个瓶子中至少要有1颗巧克力豆,随后这个人从第i个瓶子中拿走一颗豆子并在j,k中各放入一粒豆子(j可能等于k)。如果轮到某人而他无法按规则取豆子,那么他将输掉比赛。你先取,求在给定每个瓶子中的最初豆子数后是否必胜,且求出第一步该如何取,第一步有多少种必胜取法?

 

sg题,此题注意每一颗豆子都是一个游戏,对每个豆子求sg.

代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 using namespace std;
 4 const int N = 25;const int M = 10005;
 5 int n,cnt,ans,f[N],a[N];bool b[M];
 6 int sg(int x)
 7 {
 8     if(x == n)return 0;
 9     if(f[x] != -1)return f[x];
10     memset(b,0,sizeof(b));
11     for(int j = x + 1;j <= n;j++) for(int k = j;k <= n;k++) b[sg(j) ^ sg(k)] = 1;
12     int ret;for(ret = 0;b[ret];ret++);return f[x] = ret;
13 }
14 int main()
15 {
16     int T;scanf("%d",&T);
17     while(T--)
18     {
19         scanf("%d",&n);ans = cnt = 0;
20         memset(f,-1,sizeof(f));
21         for(int i = 1;i <= n;i++)
22         {
23             scanf("%d",&a[i]);
24             if(a[i] & 1) ans ^= sg(i);
25         }
26         for(int i = 1;i < n;i++)
27             for(int j = i + 1;j <= n;j++) 
28                 for(int k = j;k <= n;k++) 
29                     if(!(ans ^ sg(i) ^ sg(j) ^ sg(k))) 
30                         if((++cnt) == 1) {printf("%d %d %d\n",i - 1,j - 1,k - 1);}
31         if(!cnt) puts("-1 -1 -1");printf("%d\n",cnt);
32     }
33     return 0;
34 }

 

[bzoj 1188]分裂游戏

标签:problem   name   http   nbsp   for   set   color   多少   scan   

原文地址:http://www.cnblogs.com/gcc314/p/7596938.html

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