SG函数(hdu 1847 && poj 2960 && 1849)
2014-04-14 11:50
337 查看
HDU 1847题目:点击打开链接
SG函数的一个很基础的题目
看其他人写的,除了用SG函数,还有更简便的方法,就是能被3整除的都是Cici赢。
POJ 2960题目:点击打开链接
题目就是一个变形了的nim,n堆石子,不再是选择一堆随便取,而是规定了取的数量。
也就是SG函数的应用,nim博弈中,因为选择了某一堆以后就可以取这一堆中的任意石子,也就是SG[ x ] = x,其实nim博弈中的把所以堆石子的数目异或起来来判断结果,也是用到了SG函数,因为石子数的SG值等于石子数本身(SG[ x ] = x),所以为了简单就直接把石子数都异或起来,而这一题因为SG[ x ] = x不成立了,所以要把每次SG求出来,再求SG值异或和来判断结果。
HDU1849
赤裸裸的nim博弈,当然,如上面那题所说,也可以用SG函数来做,因为nim博弈,SG[ x ] = x。
SG函数的一个很基础的题目
看其他人写的,除了用SG函数,还有更简便的方法,就是能被3整除的都是Cici赢。
#include <stdio.h> #include <string.h> int s[11] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024}; int sg[1010]; int getsg(int x) { int i; if(sg[x] != -1) return sg[x]; bool hash[110]; memset(hash, 0, sizeof(hash)); for(i = 0; i < 11; i++) { if(x >= s[i]) { sg[x - s[i]] = getsg(x - s[i]); hash[sg[x - s[i]]] = 1; } } for(i = 0; i < 110; i++) { if(hash[i] == 0) break; } return i; } int main (void) { int i; memset(sg, -1, sizeof(sg)); sg[0] = 0; for(i = 1; i < 1010; i++) sg[i] = getsg(i); int n; while(scanf("%d", &n) != EOF) { if(sg == 0) printf("Cici\n"); else printf("Kiki\n"); } return 0; }
POJ 2960题目:点击打开链接
题目就是一个变形了的nim,n堆石子,不再是选择一堆随便取,而是规定了取的数量。
也就是SG函数的应用,nim博弈中,因为选择了某一堆以后就可以取这一堆中的任意石子,也就是SG[ x ] = x,其实nim博弈中的把所以堆石子的数目异或起来来判断结果,也是用到了SG函数,因为石子数的SG值等于石子数本身(SG[ x ] = x),所以为了简单就直接把石子数都异或起来,而这一题因为SG[ x ] = x不成立了,所以要把每次SG求出来,再求SG值异或和来判断结果。
#include <stdio.h> #include <string.h> int s[110]; int sg[10010]; int n, m; int getsg(int x) { if(sg[x] != -1) return sg[x]; int i; bool hash[110]; memset(hash, 0, sizeof(hash)); for(i = 0; i < n; i++) { if(x >= s[i]) { sg[x - s[i]] = getsg(x - s[i]); hash[sg[x - s[i]]] = 1; } } for(i = 0; i < 110; i++) { if(hash[i] == 0) break; } return i; } int main (void) { int i; while(scanf("%d", &n) != EOF) { if(n == 0) break; char ans[110], k = 0; int a, j, l; for(i = 0; i < n; i++) scanf("%d", &s[i]); memset(sg, -1, sizeof(sg)); sg[0] = 0; for(i = 1; i < 10010; i++) sg[i] = getsg(i); /* for(i = 0; i < 8; i++) { printf("%d ", sg[i]); } printf("\n"); */ scanf("%d", &m); for(i = 0; i < m; i++) { int sum = 0; scanf("%d", &l); for(j = 0; j < l; j++) { scanf("%d", &a); sum ^= sg[a]; } if(sum == 0) ans[k ++] = 'L'; else ans[k ++] = 'W'; } for(i = 0; i < k; i++) printf("%c", ans[i]); printf("\n"); } return 0; }
HDU1849
赤裸裸的nim博弈,当然,如上面那题所说,也可以用SG函数来做,因为nim博弈,SG[ x ] = x。
#include <stdio.h> #include <string.h> int sg[1010]; int getsg(int x) { int i; if(sg[x] != -1) return sg[x]; bool hash[1010]; memset(hash, 0, sizeof(hash)); for(i = 1; i < 1010; i++) {//注意i从1开始 if(x >= i) { sg[x - i] = getsg(x - i); hash[sg[x - i]] = 1; } if(x < i) break; } for(i = 0; i < 1010; i++) { if(hash[i] == 0) break; } return i; } int main (void) { int n, a, i; memset(sg, -1, sizeof(sg)); sg[0] = 0; for(i = 1; i < 1010; i++) sg[i] = getsg(i); while(scanf("%d", &n) != EOF) { if(n == 0) break; int sum = 0; for(i = 0; i < n; i++) { scanf("%d", &a); sum ^= sg[a]; } if(sum == 0) printf("Grass Win!\n"); else printf("Rabbit Win!\n"); } return 0; }
相关文章推荐
- HDU 1536 && POJ 2960 S-Nim SG函数
- 8月12号的(算是)组队赛吧。HDU 3790&&HDU 3665&&HDU 1869&&POJ 1847
- ACM-SG函数之S-Nim——hdu1536 hdu1944 poj2960
- hdu 1536 S-Nim|| poj 2960 S-Nim (sg函数)
- SG函数模板 hdu 1848/1847/1849/1850/1851
- POJ 1316 && HDU 1128 Self Numbers(水~)
- poj 2559 & hdu 1506 Largest Rectangle in a Histogram 笛卡尔树
- POJ 3346 && HDU 2416 Treasure of the Chimp Island(bfs)
- HDU - 1003 - Max Sum && POJ - 1050 - To the Max (经典DP问题)
- hdu 1671 Phone List && POJ 3630 Phone List(静态申请空间)
- HDU 2715 && POJ 2140 Herd Sums (考虑一个近似)
- POJ 1562 && HDU 1241 Oil Deposits(dfs)
- POJ 3480 & HDU 1907 John(尼姆博弈变形)
- poj 1003&&HDU 1056 && nyoj 156 Hangover【水题】
- hdu 1542 & & poj 1151
- poj 1466 && hdu 1068Girls and Boys(最大独立集)
- poj 2960 S-Nim(sg函数)
- POJ 1308 && HDU 1325 Is It A Tree?(并查集)
- poj 2421&&hdu 1102 Constructing Roads(最小生成树)
- HDU 1532 && POJ 1273 Drainage Ditches