1. 程式人生 > >POJ1753 Flip Game

POJ1753 Flip Game

題目連結:http://poj.org/problem?id=1753

大致題意:翻轉游戲在一個長方形的4x4場地上進行,在其16個方格中分別放置雙面棋子。每個棋子的一面是白色,另一面是黑色,每個都是黑色或白色朝上。每一輪你翻轉3至5個,將被翻轉的棋子的顏色從黑色改為白色,反之亦然。根據以下規則,每輪選擇要翻轉的棋子: ①選擇16箇中的任何一個②將所選擇棋子以及該棋子相鄰的上下左右棋子翻轉(如果有的話)

解題思路:

①對於每個格子,它要麼反轉0次,要麼反轉1次(當然,它的鄰格子也跟著反轉),因為它反轉偶數次和反轉0次的效果是一樣的,同理反轉奇數次的效果和反轉1次的效果是一樣的。
②由於只有16個格子,我們可以選擇0個格子,1個格子,2個格子,3個格子......進行反轉,總的選擇情況為

③當0個格子被反轉時,看它是否為純色,否則選擇一個格子進行反轉(有16種選擇),看反轉後是否為純色,否則選擇兩個格子進行反轉(有120種選擇),看反轉後是否為純色。
④只要③中有純色出現,就停止③,輸出相應的被選擇的格子個數,結束。如果16個格子都被翻轉了,還是沒變成純色,則輸出“Impossible”。

⑤分別寫一個判斷是否一個顏色的judge函式和一個翻轉flip函式,在這裡可以將棋盤擴大成6*6,這樣保證最中間的4*4,及題目所給的棋盤的每一個棋子都有上下左右棋子。

 ⑥設所要翻轉的棋子為(i,j),則對這個棋子進行翻轉時需要同時翻動(i-1,j).(i+1,j)(i,j)(i,j-1)(i,j+1),這五個棋子,所以在最初可以設定一個r={-1,1,0,0,0},c={0,0,-1,1,0},便於翻轉函式flip的編寫。

棋盤
  0 1 2 3 4 5
0            
1   棋子 棋子 棋子 棋子  
2   棋子 棋子 棋子 棋子  
3   棋子 棋子 棋子 棋子  
4   棋子 棋子 棋子 棋子  
5            

 


AC程式碼:

 

 

#include <iostream>
using namespace std;
bool chess[6][6] = {0};
bool flag;
int deep;
int step;
int row[5] = {-1,1,0,0,0};
int col[5] = {0,0,-1,1,0};

int judge()//判斷是不是全黑或全白
{
    for(int i=1; i<5; i++)
        for(int j=1; j<5; j++)
            if(chess[i][j] != chess[1][1])
                return 0;
    return 1;
}

void flip(int r,int c)//翻棋
{
    for(int i=0; i<5; i++)
        chess[r+row[i]][c+col[i]] =!chess[r+row[i]][c+col[i]];
}

void dfs(int r,int c,int deep)
{
    if(deep == step){
        flag = judge();
        return;
    }
    if(flag||r==5)
        return;
        
    //翻棋
    flip(r,c);
    if(c<4)
        dfs(r,c+1,deep+1);
    else
        dfs(r+1,1,deep+1);
        
    //不符合則翻回來
    flip(r,c);
    if(c<4)
        dfs(r,c+1,deep);
    else
        dfs(r+1,1,deep);
    return;
}
int main()
{
    char temp;
    int i,j;
    for(i=1; i<5; i++){
        for(j=1; j<5;j++){
            cin >> temp;
            if(temp == 'b')
                chess[i][j] = 1;
        }
    }
    for(step=0; step<16; step++){
        dfs(1,1,0);
        if(flag)
            break;
    }
    if(flag)
        cout << step << endl;
    else
        cout << "Impossible" << endl;
    return 0;
}