UVa 141 The Spot Game

來源:互聯網
上載者:User

題目連結:

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=77

類型: 雜湊判重 + 類比


原題:

The game of Spot is played on an NxN 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 and Output

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 will consist of one line for each game indicating which player won and on which move, or that the game ended in a draw.

Sample input

21 1 +2 2 +2 2 -1 2 +21 1 +2 2 +1 2 +2 2 -0

Sample output

Player 2 wins on move 3Draw


題目大意:

有一個在N*N棋盤上玩的遊戲叫做Spot,  它由兩個玩家輪流在棋盤上放置棋子或移除棋子, 一旦其中一個玩家放置或者移除棋子之後,那個棋盤的擺放狀態或者這個轉檯旋轉90度,180度是之前是出現過的,那麼他就輸了。 


分析與總結:

看了下我做這題的提交記錄, 一共WA了17次

到底是什麼原因使得這並不難題的一題讓我WA得徹底噁心了?讓我們走近科學。

讓我WA的原因:

1.  棋盤並不是4*4的,而是N*N的。  WA了n次。

2.  旋轉問題。 題目其實說得有點含糊,只是說旋轉90度和180度。 我就以為共有4種狀態要判斷之前是否出現過,但是題目上又說了 (plus one other not shown)  ,也就是說其實還有一個狀態沒有給出映像。 還有一個是什麼呢? 於是把題目給的映像通過旋轉函數列印了出來,
發現最後一副圖是不一樣的,通過旋轉方向根本就得不到。 這幅圖實際上是第一個的鏡面反射的圖。 所以題目說的還有一個沒有顯示出來的,是旋轉180度的那個映像。 因為這個原因又WA了n次。


這樣的錯誤說明我讀題還是太浮躁了,沉不下心來好好讀懂題意,看了個大概知道了原理和思路就直接做了,以後一定要改掉這個習慣。


糾正了這兩個錯誤後, 成功AC。

/* *  UVa  141 - The Spot Game  *  Time: 0.044s (UVa) *  Author: D_Double * */#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef int State[52][52];State board, que[105];const int HashSize = (1<<16);int N, nState, flag, head[HashSize], next[HashSize];// 類比得出旋轉後的狀態inline void rotate(State &next, State &s, int dir){    if(!dir) return;    if(dir==1){ // 順時針90度        for(int i=0, x=0; i<N; ++i, ++x){            for(int j=N-1, y=0; j>=0; --j, ++y)                next[x][y] = s[j][i];        }    }    else if(dir==2){ // 逆時針90度        for(int i=N-1, x=0; i>=0; --i, ++x){            for(int j=0, y=0; j<N; ++j, ++y)                next[x][y] = s[j][i];        }    }    else if(dir==3){ // 180度        for(int i=N-1, x=0; i>=0; --i, ++x){            for(int j=N-1, y=0; j>=0; --j, ++y )                next[x][y] = s[i][j];        }     }    else if(dir==4){ // 鏡面反射        for(int i=0, x=0; i<N; ++i, ++x){            for(int j=N-1, y=0; j>=0; --j, ++y)                next[x][y] = s[i][j];        }      }}inline int hash(State &s){    int v=0;    for(int i=0; i<N; ++i)        for(int j=0; j<N; ++j)            v = ((v<<1)+s[i][j]) % HashSize;    return v%HashSize;}int search(State &s){    int h=hash(s);    int u=head[h];    while(u){        if(memcmp(que[u], s, sizeof(s))==0) return 1;        u = next[u];    }    return 0;}inline void insert(int s){    int h=hash(que[s]);    int u=head[h];    while(u){        u = next[u];    }    next[s] = head[h] ;    head[h] = s;} bool add_hash(int s){    State state[5];    memcpy(state[0], que[s], sizeof(que[s]));    for(int i=0; i<=4; ++i){        rotate(state[i], que[s], i);        if(search(state[i])) return false;     }    insert(s);     return true;}inline void init(){    nState = 2;    memset(head, 0, sizeof(head));    memset(board, 0, sizeof(board));    memcpy(que[1], board, sizeof(board));    insert(1);    flag=0;}int main(){    int a, b, winner, step;    char ch;      while(scanf("%d", &N), N){        init();        for(int i=0; i<2*N; ++i){            scanf("%d %d %c",&a,&b,&ch);            if(ch=='+') board[a-1][b-1] = 1;            else board[a-1][b-1] = 0;            memcpy(que[nState], board, sizeof(board));            if(!flag && !add_hash(nState)){                winner = !(i&1);  step = i+1; flag=1;            }            ++nState;        }        if(flag) printf("Player %d wins on move %d\n", winner+1, step);        else printf("Draw\n");    }       return 0;}

——  生命的意義,在於賦予它意義。

               原創 http://blog.csdn.net/shuangde800 , By   D_Double  (轉載請標明)


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.