题意:两个人下棋,棋盘刚开始是空的,第一个人先下,先输入棋盘的尺寸n*n, 棋子放置的位置,然后如果是‘+’,要放一个黑棋,如果是‘-',要拿走那个位置的黑棋,判断胜负的标准是,在一个人操作完成后,判断当前的棋盘的盘面(或者旋转90、180、270度)是否已经在之前出现过,如果是就是另个人胜出,并且输出是哪个人在第几次操作成功的,如果一同操作了2 × n也没分出胜负就是平局。
题解:用存放string的map判重,然后矩阵的旋转也需要注意。
顺时针90度 m是原数组,temp是旋转后储存的数组,n是数组尺寸。
for (int i = 0, k = n - 1; i < n; i++, k--)
for (int j = 0; j < n; j++)
temp[j][k] = m[i][j];
逆时针90度 变量意思同上
for (int i = 0; i < n; i++)//逆时针90
for (int j = 0, k = n - 1; j < n; j++, k--)
temp[k][i] = m[i][j];
#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
#include <cmath>
#include <iostream>
using namespace std;
const int N = 55;
int n, row, col, ans1, ans2, flag;
string keep;
char m[N][N];
char c;
map<string, int> vis;
string hash(char temp[][N]) {
string str = "";
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
str += temp[i][j];
if (!vis[str])
return str;
return "hehe";
}
int judge() {
keep = hash(m);
if (keep == "hehe")
return 0;
char temp[N][N];
for (int i = 0, k = n - 1; i < n; i++, k--) //顺时针90度
for (int j = 0; j < n; j++)
temp[j][k] = m[i][j];
if (hash(temp) == "hehe")
return 0;
char temp2[N][N];
for (int i = 0, k = n - 1; i < n; i++, k--) //旋转180度
for (int j = 0; j < n; j++)
temp2[j][k] = temp[i][j];
if (hash(temp2) == "hehe")
return 0;
for (int i = 0; i < n; i++)//逆时针90度
for (int j = 0, k = n - 1; j < n; j++, k--)
temp[k][i] = m[i][j];
if (hash(temp) == "hehe")
return 0;
return 1;
}
int main() {
while (scanf("%d", &n) && n) {
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
m[i][j] = '0';
vis.clear();
flag = 0;
for (int i = 1; i <= (2 * n); i++) {
scanf("%d%d %c", &row, &col, &c);
if (c == '+')
m[row - 1][col - 1] = '1';
else
m[row - 1][col - 1] = '0';
if (!flag && !judge()) {
ans1 = i % 2 + 1;
ans2 = i;
flag = 1;
}
vis[keep] = 1;
}
if (flag == 1)
printf("Player %d wins on move %d\n", ans1, ans2);
else
printf("Draw\n");
}
}