The Spot Game |
题目意思:两个人玩棋时有两种下棋方式,或者在空地放置棋子,或者捡起其中一个棋子,如果棋盘当前格局在四种转换的状态下中任意一种状态下的格局在之前出现过,那就意味着下到这盘棋的人输了,你要输出的就是这时总共下的步数和谁赢了,如果下到最后填满了棋盘,则输出“Draw”
解题思路:题目就说明了思路,用set保存之前出现的格局,然后每一步下的棋都去比较,输出判断的信号随时保持更新
心得:用set时如果不是基本类型就意味着要自己写operator,而且find()的时候也是依据你写的operator的返回值判断
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<set> 5 #include<string> 6 #define SIZE 51 7 using namespace std; 8 typedef struct type{ 9 char submaze[SIZE][SIZE]; 10 }type; 11 12 struct cmp{ 13 bool operator()(type a, type b) const{ 14 return memcmp(a.submaze, b.submaze, sizeof(char)*SIZE*SIZE) < 0; 15 } 16 }; 17 18 set<type, cmp>vis; 19 char maze[SIZE][SIZE]; 20 char swapMaze[SIZE][SIZE]; 21 int n; 22 bool Traverse(int x, int y, char flag) 23 { 24 type temp; 25 maze[x][y] = flag == '+' ? '.' : 'x'; 26 memcpy(swapMaze, maze, sizeof(maze)); 27 memcpy(temp.submaze, swapMaze, sizeof(maze)); 28 if(vis.find(temp) != vis.end()) return false; 29 for(int t=0; t<3; ++t) 30 { 31 for(int i=0; i<n; ++i) 32 for(int j=0; j<n; ++j) 33 temp.submaze[j][i] = swapMaze[n-1-i][j]; 34 if(vis.find(temp) != vis.end()) return false; 35 else memcpy(swapMaze,temp.submaze, sizeof(maze)); 36 } 37 38 memcpy(temp.submaze, maze, sizeof(maze)); 39 vis.insert(temp); 40 return true; 41 } 42 43 int main() 44 { 45 #ifndef ONLINE_JUDGE 46 freopen("input.txt","r",stdin); 47 #endif 48 while(cin>>n && n) 49 { 50 int step = 0; 51 vis.clear(); 52 memset(maze, 0, sizeof(maze)); 53 for(int i=0; i<n*n; ++i)maze[i/n][i%n] = 'x'; 54 for(int i=1; i<=2*n; ++i) 55 { 56 int c, r; 57 char select; 58 cin>>c>>r; 59 getchar(); 60 cin>>select; 61 if(Traverse(c-1, r-1, select) == false && step == 0) step = i; 62 } 63 if(step != 0) 64 { 65 int num = 0; 66 num = step%2 == 0 ? 1 : 2; 67 cout<<"Player "<<num<<" wins on move "<<step<<endl; 68 } 69 else cout<<"Draw"<<endl; 70 } 71 return 0; 72 }