sg函数入门题
2015-07-24 20:10
232 查看
poj 2311:
题意:
给一个 w * h 的矩形纸片,每次可以剪一刀,谁先剪到1 * 1谁就赢。
解析:
用sg函数来找必胜态和必败态,然后类似记忆化搜索,不断往下找。
代码:
poj 2425:
题意:
给n个点,然后给定这n个点的拓补图,有向无环。
然后给m个棋子,在哪几个点上。
现在有俩玩家来轮流移动这些棋子,谁先没办法移动所有的棋子谁输。
解析:
sg函数入门用来解释时用的就是这个模型。
代码:
poj2068:
题意:
题意是圆桌上有2n个人,奇数一队,偶数一队,每个人都有一个拿走棋子的最高限额,问你最后1对能否获胜。
代码:
poj 3537:
代码:
题意:
给一个 w * h 的矩形纸片,每次可以剪一刀,谁先剪到1 * 1谁就赢。
解析:
用sg函数来找必胜态和必败态,然后类似记忆化搜索,不断往下找。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <set> #include <climits> #include <cassert> #define LL long long using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 200 + 10; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); int sg[maxn][maxn]; int dfs(int w, int h) { if (sg[w][h] != -1) return sg[w][h]; bool vis[maxn]; memset(vis, false, sizeof(vis)); int res = 0; for (int i = 2; i <= w / 2; i++) { res = dfs(i, h) ^ dfs(w - i, h); vis[res] = true; } for (int i = 2; i <= h / 2; i++) { res = dfs(w, i) ^ dfs(w, h - i); vis[res] = true; } res = 0; while (vis[res]) res++; return sg[w][h] = res; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAl memset(sg, -1, sizeof(sg)); int w, h; while (~scanf("%d%d", &w, &h)) { if (dfs(w, h)) printf("WIN\n"); else printf("LOSE\n"); } return 0; }
poj 2425:
题意:
给n个点,然后给定这n个点的拓补图,有向无环。
然后给m个棋子,在哪几个点上。
现在有俩玩家来轮流移动这些棋子,谁先没办法移动所有的棋子谁输。
解析:
sg函数入门用来解释时用的就是这个模型。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <set> #include <climits> #include <cassert> #define LL long long using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 1000 + 10; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); int n; int sg[maxn]; vector<int> g[maxn]; int dfs(int u) { if (sg[u] != -1) return sg[u]; bool vis[maxn]; memset(vis, false, sizeof(vis)); int sz = g[u].size(); for (int i = 0; i < sz; i++) { int v = g[u][i]; int t = dfs(v); vis[t] = true; } int res = 0; while (vis[res]) res++; return sg[u] = res; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAl while (~scanf("%d", &n) && n) { for (int i = 0; i < n; i++) { g[i].clear(); } memset(sg, -1, sizeof(sg)); for (int i = 0; i < n; i++) { int k; scanf("%d", &k); if (k == 0) sg[i] = 0; for (int j = 0; j < k; j++) { int t; scanf("%d", &t); g[i].push_back(t); } } int x; while (scanf("%d", &x) && x) { int ans = 0; while (x--) { int t; scanf("%d", &t); ans ^= dfs(t); } if (ans) printf("WIN\n"); else printf("LOSE\n"); } } return 0; }
poj2068:
题意:
题意是圆桌上有2n个人,奇数一队,偶数一队,每个人都有一个拿走棋子的最高限额,问你最后1对能否获胜。
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <set> #include <climits> #include <cassert> #define LL long long using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 10 + 10; const int maxs = 8192 + 10; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); int sg[maxn][maxs]; int a[maxn]; int n, s; int dfs(int x, int sum) { if (sg[x][sum] != -1) return sg[x][sum]; for (int i = 1; i <= a[x]; i++) { int t = sum - i; if (t < 0) break; int y; if ((n << 1) <= x + 1) y = 0; else y = x + 1; if (dfs(y, t) == 0) return sg[x][sum] = 1; } return sg[x][sum] = 0; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAl while (~scanf("%d", &n) && n) { scanf("%d", &s); for (int i = 0; i < (n << 1); i++) { scanf("%d", &a[i]); } memset(sg, -1, sizeof(sg)); for (int i = 0; i < (n << 1); i++) { sg[i][0] = 1; } printf("%d\n", dfs(0, s)); } return 0; }
poj 3537:
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> #include <stack> #include <vector> #include <queue> #include <map> #include <set> #include <climits> #include <cassert> #define LL long long using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 2000 + 10; const int maxs = 8192 + 10; const double eps = 1e-8; const double pi = acos(-1.0); const double ee = exp(1.0); int sg[maxn]; int dfs(int x) { if (x < 0) return 0; if (sg[x] != -1) return sg[x]; bool vis[maxn]; memset(vis, false, sizeof(vis)); for (int i = 1; i <= x; i++) { int t = dfs(i - 3) ^ dfs(x - i - 2); vis[t] = true; } int res = 0; while (vis[res]) res++; return sg[x] = res; } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); #endif // LOCAl memset(sg, -1, sizeof(sg)); int n; while (~scanf("%d", &n)) { if (dfs(n)) puts("1"); else puts("2"); } return 0; }
相关文章推荐
- [多校2015.01.1012 博弈] hdu 5299 Circles Game
- iOS指针第一天
- linux 64位系统 mod_encoding解决中文文件名不能下载问题
- java面向对象--06
- 关于RTP中的时间戳问题
- 阿里云 Centos6.5 mysql5.6 数据文件迁移
- Web概述
- [树状数组&线段树]HDU 2492 ping pong
- hdoj 1509 Windows Message Queue(优先队列)
- (八十五)应用程序间的跳转与消息传递
- 【CODEFORCES】 B. Dreamoon and WiFi
- HDU2224&POJ2677 双调旅行商问题
- unity内存优化和客户端表格读取方法内存比较
- (八十五)应用程序间的跳转与消息传递
- poj-2758 Checking the Text
- 解析XML文件的方法
- qsort排序
- Android Api Demos登顶之路(二)
- 最近忐忑的心情
- App15_列出某个文件下所有目录(树形)