传送门UVa 141 & HOJ 1186 - The Spot Game
这道题本来是挺简单的,但是折腾了四五个小时。。
一开始看成4 * 4了,WA了六七次。
然后以为一开始空的棋盘也算一种状态,WA了两三次
然后哈希表开太大了,又WA了两次。
然后发现本来存状态的数组是4 * 4的,后来没有改回55 * 55,又WA。。
真是。。刺激啊。。
题意:给一个N * N棋盘,当下一步棋的时候,看它的四种状态是不是已经存在。如果不存在,要把它的四种状态存入。接着下。如果超出步数(2 * n) 直接输出draw。
代码太难看了,大家还是去参考别人的吧TAT。
幸好HOJ上有这题,判题也很快,可以给我瞎折腾。。要是放在UVa,一题得等上三四分钟。。那还得了。。
#include <cstdio>
#include <cstring>
using namespace std;
const int HashSize = 2000;
typedef int State[55][55];
int head[HashSize], next[HashSize], n;
State result[2000], chess;
State right, left, rright;
int BKDHash(State &s);
bool TryToInsert(int s);
bool Search(int s);
void Insert(int s);
int main()
{
//freopen("input.txt", "r", stdin);
int i, j, x, y, k, cnt;
char symbol;
bool skipFlag;
while (scanf("%d", &n), n)
{
skipFlag = false;
memset(head, 0, sizeof(head));
memset(chess, 0, sizeof(chess));
cnt = 1, k = 1;
for (i = 0; i < 2 * n; i++)
{
scanf("%d%d%*c%c", &x, &y, &symbol);
if (skipFlag)
continue;
if (symbol == '+')
chess[x][y] = 1;
else
chess[x][y] = 0;
memcpy(result[k], chess, sizeof(chess));
if (Search(k)) //if this state hasn't occureed, go on.
{
Insert(k++);
memcpy(result[k], right, sizeof(right));
Insert(k++);
memcpy(result[k], left, sizeof(left));
Insert(k++);
memcpy(result[k], rright, sizeof(rright));
Insert(k++);
cnt++;
}
else
{
printf("Player %d wins on move %d\n", cnt % 2 + 1, cnt);
skipFlag = true; //Open the flag.
}
}
if (i == 2 * n && !skipFlag) //reach the limits.
printf("Draw\n");
}
return 0;
}
int BKDHash(State &s)
{
int seed = 131;
int value = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
value = value * seed + s[i][j];
return (value & 0x7FFFFFFF) % HashSize;
}
bool Search(int s)
{
//check 4 states if has occurred.
State temp;
State &cur = result[s];
//rotate 90° clockwise.
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
right[j][n + 1 - i] = cur[i][j];
int v = BKDHash(right);
int u = head[v];
while (u)
{
if (memcmp(result[s], result[u], sizeof(result[u])) == 0)
return false;
u = next[u];
}
//rotate 90° Counterclockwise
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
left[n + 1 - j][i] = cur[i][j];
v = BKDHash(left);
u = head[v];
while (u)
{
if (memcmp(result[s], result[u], sizeof(result[u])) == 0)
return false;
u = next[u];
}
//rotate 180°
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
rright[n + 1 - i][n + 1 - j] = cur[i][j];
v = BKDHash(rright);
u = head[v];
while (u)
{
if (memcmp(result[s], result[u], sizeof (result[u])) == 0)
return false;
u = next[u];
}
//At last check the original state
v = BKDHash(cur);
u = head[v];
while (u)
{
if (memcmp(result[s], result[u], sizeof(result[u])) == 0)
return false;
u = next[u];
}
return true;
}
void Insert(int s)
{
int v = BKDHash(result[s]);
int u = head[v];
head[v] = s;
}