/* *State: 1536 343MS 368K 1164 B C++ *题目大意: * 给定一个集合S,然后规定每一堆石头只能取集合S中 * 个数,然后要求出所有sg值,并判断结果。 *解题思路: * 典型的求sg函数即可求解。 *题目困惑: * 题目困惑了好久,最后我把错误排除到了求sg函数上, * 可是还是觉得没有问题,最后还是看了别人的解题报告, * 眼睛一扫,一秒就知道了问题所在。 * 其实我一开始就想到了S集合要排序,但是没有细想,就 * 过了,结果困扰了我这么久。 * * //忘记了排序,杯具了很久,排除了很多问题,最后觉得 * //问题是出在求sg值上面了,结果排除问题也是对的,但是 * //偏偏没有考虑到是f域里面要从小到大排序,因为求sg的 * //时候,我的判断条件是 * //while(i >= f[h] && h < n) * // vst[sg[i - f[h++]]] = true;受这个影响,所以一定 * //要排序。 */
View Code
1 #include <iostream> 2 #include <stdio.h> 3 #include <algorithm> 4 using namespace std; 5 6 const int MAX = 10005; 7 int f[105], sg[MAX]; 8 9 void get_sg(int n) 10 { 11 memset(sg, 0, sizeof(sg)); 12 bool vst[MAX]; 13 for(int i = 0; i < MAX; i++) 14 { 15 memset(vst, false, sizeof(vst)); 16 int h = 0, j; 17 while(i >= f[h] && h < n) 18 vst[sg[i - f[h++]]] = true; 19 for(j = 0; j <= i; j++) 20 { 21 if(!vst[j]) 22 { 23 sg[i] = j; 24 break; 25 } 26 } 27 } 28 return ; 29 } 30 31 void view_arr(int arr[], int n) 32 { 33 for(int i = 0; i < n; i++) 34 cout << arr[i] << endl; 35 return ; 36 } 37 38 int main(void) 39 { 40 41 #ifndef ONLINE_JUDGE 42 freopen("in.txt", "r", stdin); 43 #endif 44 45 int n; 46 while(scanf("%d", &n), n) 47 { 48 for(int i = 0; i < n; i++) 49 scanf("%d", &f[i]); 50 51 //忘记了排序,杯具了很久,排除了很多问题,最后觉得 52 //问题是出在求sg值上面了,结果排除问题也是对的,但是 53 //偏偏没有考虑到是f域里面要从小到大排序,因为求sg的 54 //时候,我的判断条件是 55 //while(i >= f[h] && h < n) 56 // vst[sg[i - f[h++]]] = true;受这个影响,所以一定 57 //要排序。 58 59 sort(f, f + n); 60 get_sg(n); 61 int m; 62 scanf("%d", &m); 63 for(int i = 0; i < m; i++) 64 { 65 int h, tmp, yihuo = 0; 66 scanf("%d", &h); 67 for(int j = 0; j < h; j++) 68 { 69 scanf("%d", &tmp); 70 yihuo ^= sg[tmp]; 71 } 72 if(!yihuo) 73 printf("L"); 74 else 75 printf("W"); 76 } 77 printf("\n"); 78 } 79 return 0; 80 }