/*
*State: ECNU 1328  Yes     236K  0MS    C++     0.96K
*题目大意:
*        给定red、green、blue三种长度分别为c、z、n的矩形条纹,要求
*        用这三种矩形条纹来cover大小为p x 1的game board,第一个不能
*        再cover的选手为输。问先手是否能赢。
*解题思路:
*        好像是变种了的博弈,想想,原来可以用sg来模拟,其实就是先拿掉一些,
*        再把一堆变成两堆的那种Nim博弈。
*/
View Code
 1 #include <iostream>
 2 using namespace std;
 3 
 4 const int MAX = 1024;
 5 int a[3], sg[MAX];
 6 
 7 void get_sg()
 8 {
 9     memset(sg, -1, sizeof(sg));
10     bool vst[MAX] = {false};
11     for(int i = 0; i < MAX; i++)
12     {
13         memset(vst, false, sizeof(vst));
14         for(int j = 0; j < 3; j++)
15         {
16             if(i >= a[j])
17             {
18                 int t = i - a[j], t2 = t / 2;
19                 for(int k = 0; k <= t2; k++)
20                 {
21                     int s = sg[k] ^ sg[t - k];
22                     vst[s] = true;
23                 }
24             }
25         }
26         for(int j = 0; j < MAX; j++)
27         {
28             if(!vst[j])
29             {
30                 sg[i] = j;
31                 break;
32             }
33         }
34     }
35     return ;
36 }
37 
38 int main(void)
39 {
40 #ifndef ONLINE_JUDGE
41     //freopen("in.txt", "r", stdin);
42 #endif
43     while(scanf("%d %d %d", &a[0], &a[1], &a[2]) == 3)
44     {
45         get_sg();
46         int m;
47         scanf("%d", &m);
48         for(int i = 0; i < m; i++)
49         {
50             int p;
51             scanf("%d", &p);
52             if(sg[p])
53                 printf("1\n");
54             else
55                 printf("2\n");
56         }    
57     }
58     return 0;
59 }
posted on 2012-08-04 16:34  cchun  阅读(210)  评论(0编辑  收藏  举报