HDU1425 A Chess Game
生活随笔
收集整理的這篇文章主要介紹了
HDU1425 A Chess Game
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:http://acm.hdu.edu.cn/showproblem.php?pid=1524
思路:題目就是給你一個拓撲圖,然后指定點的位置放棋子,然后兩人輪流移動棋子(題目中的邊的關系),直到一方不能移動。
SG函數裸題,之前接觸的兩道一個是推的關系,一個是取石子的。這個比較明顯的就是出度為0的點,sg值為0。然后深搜得到其他點的sg值,棋子的異或和為0 則P必敗,否則N必勝
由于遞歸寫的很不好,導致沒過。最開始竟然用隊列隨便寫了一個。(TLE),后來嘗試用dfs寫了,WA,迫于無奈只好看題解了(果真就是dfs)? 后面附有錯誤代碼
AC代碼:
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <string> #include <vector> #include <set> #include <map> #include <queue> #include <algorithm> #include <sstream> #include <stack> using namespace std; #define in freopen("in.txt", "r", stdin); typedef long long ll; const int inf = 0x3f3f3f3f;vector<int> G[1010]; int sg[1010]; int n, xi, u, v, m, x; int dfs(int id) { //為什么感覺不是太難寫,自己就是寫不出來。 T_T !!!if(sg[id] != -1) return sg[id];//已經有了直接返回 bool vis[1010];//標記,求mex memset(vis, false, sizeof(vis));for(int i = 0; i < G[id].size(); i++) {sg[G[id][i]] = dfs(G[id][i]);//遞歸求出后繼sg值 vis[sg[G[id][i]]]= true;//標記后繼的sg值 }for(int i = 0; ; i++) {if(!vis[i]) {return sg[id] = i;//求自己的sg值 }} }int main() {while(~scanf("%d", &n)) {memset(G, 0, sizeof(G));for(int i = 0; i < n; i++) {scanf("%d", &xi);while(xi--) {//存圖 scanf("%d", &v);G[i].push_back(v);}}memset(sg, -1, sizeof(sg));while(scanf("%d", &m) && m) {int sum = 0;while(m--) {//異或和 scanf("%d", &x);sum ^= dfs(x);}if(sum)printf("WIN\n");elseprintf("LOSE\n");}} }瞎寫的隊列代碼(TLE)
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <string> #include <vector> #include <set> #include <map> #include <queue> #include <algorithm> #include <sstream> #include <stack> using namespace std; #define in freopen("in.txt", "r", stdin); typedef long long ll; const int inf = 0x3f3f3f3f;vector<int> G[1010]; int sg[1010]; int n, xi, u, v, m, x;void SG() {queue<int> q;for(int i = 0; i < n; i++) {if(G[i].size() == 0)sg[i] = 0;else q.push(i);//需要求的點i }bool vis[1010];while(!q.empty()) memset(vis, false, sizeof(vis));int u = q.front();bool flag = false;for(int j = 0; j < G[u].size(); j++) { if(sg[G[u][j]] != -1) {//如果后繼有一個不知道的就換 vis[sg[G[u][j]]] = true;} else {flag = true;q.push(u);q.pop();}}if(flag == false) {//說明這個點的sg值可以求 for(int j = 0; j <= 1010; j++) {if(vis[j] == false) {sg[u] = j;break;}}q.pop();}} }int main() {while(~scanf("%d", &n)) {memset(G, 0, sizeof(G));for(int i = 0; i < n; i++) {scanf("%d", &xi);if(xi == 0)continue;else {while(xi--) {scanf("%d", &v);G[i].push_back(v);}}}memset(sg, -1, sizeof(sg));SG();while(~scanf("%d", &m) && m) {int sum = 0;while(m--) {scanf("%d", &x);sum ^= sg[x];}if(sum)printf("WIN\n");elseprintf("LOSE\n");}} }自己寫的錯誤DFS代碼:
#include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <stdlib.h> #include <string> #include <vector> #include <set> #include <map> #include <queue> #include <algorithm> #include <sstream> #include <stack> using namespace std; #define in freopen("in.txt", "r", stdin); typedef long long ll; const int inf = 0x3f3f3f3f;vector<int> G[1010]; int sg[1010], indegree[1010]; int n, xi, u, v, m, x, topu; vector<int> GB[1010];//該點的 后繼值 void SG(int id) {for(int i = 0; i < G[id].size(); i++) {//我剛開始也寫的bool vis[maxn] 但是我以為這個vis的狀態會被破壞 T_T if(sg[G[id][i]] != -1)GB[id].push_back(sg[G[id][i]]);else {SG(G[id][i]);//瞎寫我以為這樣求下去,sg[G[id][i]]的值就有了 但是我還是感覺就有了。。。。 GB[id].push_back(sg[G[id][i]]);}}sg[id] = *min_element(GB[id].begin(), GB[id].end()) - 1;//直接求sg值 }int main() {while(~scanf("%d", &n)) {memset(G, 0, sizeof(G));memset(GB, 0, sizeof(GB));memset(indegree, 0, sizeof(indegree));for(int i = 0; i < n; i++) {scanf("%d", &xi);if(xi == 0)continue;else {while(xi--) {scanf("%d", &v);G[i].push_back(v);indegree[v]++;//因為是一個圖,我就打算從根節點開始往下搜 }}}memset(sg, -1, sizeof(sg));for(int i = 0; i < n; i++) {if(G[i].size() == 0)sg[i] = 0;else if(indegree[i] == 0)topu = i;//根節點 }SG(topu);while(~scanf("%d", &m) && m) {int sum = 0;while(m--) {scanf("%d", &x);sum ^= sg[x];}if(sum)printf("WIN\n");elseprintf("LOSE\n");}} }?
?
轉載于:https://www.cnblogs.com/ACMerszl/p/9572947.html
總結
以上是生活随笔為你收集整理的HDU1425 A Chess Game的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 0003 无重复字符的最长子串
- 下一篇: myeclipse导入maven工程