1. 程式人生 > 其它 >UVA141 The Spot Game【模擬】

UVA141 The Spot Game【模擬】

技術標籤:# ICPC-模擬# ICPC-UVAUVA141The Spot Game

The game of Spot is played on an N × N board as shown below for N = 4. During the game, alternate players may either place a black counter (spot) in an empty square or remove one from the board, thus producing a variety of patterns. If a board pattern (or its rotation by 90 degrees or 180 degrees) is repeated during a game, the player producing that pattern loses and the other player wins. The game terminates in a draw after 2N moves if no duplicate pattern is produced before then.

Consider the following patterns:
在這裡插入圖片描述
If the first pattern had been produced earlier, then any of the following three patterns (plus one other not shown) would terminate the game, whereas the last one would not.
Input
Input will consist of a series of games, each consisting of the size of the board, N (2 ≤ N ≤ 50) followed, on separate lines, by 2N moves, whether they are all necessary or not. Each move will consist of the coordinates of a square (integers in the range 1…N) followed by a blank and a character ‘+’ or ‘-’ indicating the addition or removal of a spot respectively. You may assume that all moves are legal, that is there will never be an attempt to place a spot on an occupied square, nor to remove a non-existent spot. Input will be terminated by a zero (0).
Output
Output will consist of one line for each game indicating which player won and on which move, or that the game ended in a draw. See the Sample Output below for the exact format.
Sample Input
2
1 1 +
2 2 +
2 2 -
1 2 +
2
1 1 +
2 2 +
1 2 +
2 2 -
0
Sample Output
Player 2 wins on move 3
Draw

問題連結UVA141 The Spot Game


問題簡述:在N*N棋盤上玩Spot遊戲, 由兩個玩家輪流在棋盤上放置棋子或移除棋子, 一旦其中一個玩家放置或者移除棋子之後,那個棋盤的擺放狀態或者其旋轉90度和180度的狀態是之前出現過的狀態,那麼他就輸了。
問題分析:題目分類上是讓使用Hash和set來解決,但是題解沒有使用。記住所有的狀態,安裝擺放進行模擬,再進行狀態比較即可。
程式說明:用函式memcmp()進行狀態比較應該是快的。因為,狀態用二維bool陣列來表示,本質上是位表示。
參考連結:(略)
題記:(略)

AC的C++語言程式如下:

/* UVA141 The Spot Game */

#include <bits/stdc++.h>

using namespace std;

const int N = 50;
struct State
{
    bool board[N + 1][N + 1];
    State() {memset(board, false, sizeof(board));}
};
int n;

bool judge(State &a, State &b)
{
    return memcmp(&a.board, &b.board, sizeof(a.board)) == 0;
}

void rotat90(State &a)
{
    State t = a;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            a.board[i][j] = t.board[n + 1 - j][i];
}

int main()
{
    while(~scanf("%d", &n) && n) {
        int ans = 0;
        State b[N * 2 + 1];
        for(int i = 1; i <= n * 2; i++) {
            int row, col;
            char a[2];
            scanf("%d%d%s", &row, &col, a);

            b[i] = b[i - 1];
            b[i].board[row][col] = (a[0] == '+');
            for(int j = 1; j < i && ans == 0; j++) {
                State t = b[i];
                if(judge(t, b[j])) ans = i;
                else {
                   rotat90(t);
                   if(judge(t, b[j])) ans = i;
                   else {
                       rotat90(t);
                       if(judge(t, b[j])) ans = i;
                       else {
                           rotat90(t);
                           if(judge(t, b[j])) ans = i;
                       }
                   }
                }
            }
        }

        if(ans == 0) puts("Draw");
        else {
            int v = ans % 2 + 1;
            printf("Player %d wins on move %d\n", v, ans);
        }
    }

    return 0;
}