题目:给你一个n*n的表格,两个人轮流进行操作,每次在一个位置放上或者拿下一个棋子;
如果某一状态,之前出现过,则对方获胜,问谁获胜,如果没人获胜,输出Draw。
分析:DS,数据结构,hash函数,状态压缩。
将每一行存到一个位中,用一个一维数组表示一个状态,然后利用hash表存储查找即可。
说明:注意旋转后的状态认为是相同的。
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <cmath> using namespace std; //hash_define typedef struct node0 { long A[50]; node0 *next; }hnode; hnode* hash_head[100]; hnode hash_node[100]; int hash_size; void hash_init() { hash_size = 0; memset(hash_node, 0, sizeof(hash_node)); memset(hash_head, 0, sizeof(hash_head)); } void copy(int a[][50], int b[][50], int n) { for (int i = 0 ; i < n ; ++ i) for (int j = 0 ; j < n ; ++ j) a[i][j] = b[i][j]; } void over(int a[][50], int b[][50], int n) { for (int i = 0 ; i < n ; ++ i) for (int j = 0 ; j < n ; ++ j) a[j][i] = b[n-1-i][j]; } int tem1[50][50],tem2[50][50]; int hash_insert(int a[][50], int n) { copy(tem1, a, n); int sum = 0; for (int k = 0 ; k < 4 ; ++ k) { over(tem2, tem1, n); copy(tem1, tem2, n); sum = 0; for (int i = 0 ; i < n ; ++ i) { hash_node[hash_size].A[i] = 0; for (int j = 0 ; j < n ; ++ j) { hash_node[hash_size].A[i] += tem2[i][j]<<j; sum = (sum+tem2[i][j])%100; } } for (hnode* p = hash_head[sum] ; p ; p = p->next) { int flag = 0; for (int i = 0 ; i < n ; ++ i) if (p->A[i] != hash_node[hash_size].A[i]) { flag = 1;break; } if (!flag) return 1; } } hash_node[hash_size].next = hash_head[sum]; hash_head[sum] = &hash_node[hash_size ++]; return 0; } //hash_end int maps[50][50]; int main() { int n,x,y; char ch; while (~scanf("%d",&n) && n) { memset(maps, 0, sizeof(maps)); hash_init(); int flag = 0; for (int i = 1 ; i <= 2*n ; ++ i) { scanf("%d %d %c",&x,&y,&ch); if (ch == '+') { if (maps[x-1][y-1] && !flag) flag = i; else maps[x-1][y-1] = 1; }else { if (!maps[x-1][y-1] && !flag) flag = i; else maps[x-1][y-1] = 0; } if (hash_insert(maps, n) && !flag) flag = i; } if (!flag) printf("Draw\n"); else printf("Player %d wins on move %d\n",1+flag%2,flag); } return 0; }
原文:http://blog.csdn.net/mobius_strip/article/details/44205005