POJ1753 Flip Game

題目鏈接:http://poj.org/problem?id=1753

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

解題思路:①每個棋子翻轉的次數爲0(偶數)次或1(奇數)次。這個棋盤最多走16步,共2^{16}種狀態。將黑白色看成0、1。

                 ②以全黑或全白作爲根節點去搜索樹葉看看是否有輸入時的狀態,枚舉所有狀態,直到找到目標狀態。樹的深度就是所要翻轉的最小次數。

                 ③分別寫一個判斷是否一個顏色的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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章