题意:
两个人下棋,如果出现重复的棋局则这个人则输,重复包括旋转之后的情况,如果超过2*n次还没分出胜负则平局
思路:
先讲用到set的方法,这里把二维数组封装在结构体里面,此时set必须得手写<重载才能用count和insert函数,
这里着重提一下重载出现的错误
bool operator < (const spot& a, const spot& b){
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
if(a.arr[i][j] < b.arr[i][j]) return true;
}
return false;
}
是不行的
bool operator < (const spot& a, const spot& b)
{
int i, j;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++) {
if(a.arr[i][j] < b.arr[i][j]) return true;
else if(a.arr[i][j] > b.arr[i][j])return false;
}
return false;
}
才可以
那么我们就每执行一个动作就判断是否是一个重复的棋局(count),只判断当前是因为如果棋子数量是曾经出现过的那么旋转在之前就处理了.
如果是就不再做任何操作
如果不是,我们就将旋转的四种情况插入到set里面
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<set>
using namespace std;
const int maxn = 55;
int n;
struct spot {
bool arr[maxn][maxn];
}p;
bool operator < (const spot& a, const spot& b){
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
if(a.arr[i][j] < b.arr[i][j]) return true;
else if(a.arr[i][j] > b.arr[i][j]) return false;
}
return false;
}
void change(spot& w) {
spot a;
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
a.arr[i][j] = w.arr[j][n+1-i];
}
w = a;
}
int main() {
int a, b;
char c;
while(scanf("%d", &n) && n) {
bool flag = false;
set<spot> s;//把二位数组封装早结构体里面
memset(p.arr, false, sizeof(p.arr));
int count = 0;
for(int num=1; num<=2*n; num++) {
scanf("%d%d %c\n", &a, &b, &c);
if(flag) continue;
if(c == '+') {
p.arr[a][b] = true;
}
else p.arr[a][b] = false;
if(s.count(p)) {
flag =true;
count = num;
continue;
}
spot t(p);
for(int j=0; j<4; j++) {
s.insert(t);
change(t);
}
}
if(flag == true) {
if(count % 2 == 0) printf("Player 1 wins on move %d\n", count);
else printf("Player 2 wins on move %d\n", count);
}
else printf("Draw\n");
}
return 0;
}