/* *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 }