poj-1753題題解思路

今每天氣很好!ios

首先題意是這樣的::數組

翻蓋遊戲是在一個長方形的4x4場上進行的,其16個方格中的每個都放置了雙面的棋子。每一塊的一邊是白色的,另外一邊是黑色的,每一塊都是躺着的,要麼是黑色的,要麼是白色的。每一輪你翻轉3到5塊,從而改變他們的上邊的顏色從黑色到白色,反之亦然。每一輪將翻轉的棋子按照如下規則進行選擇:spa

    1. 選擇16件中的任何一件。
    2. 將選定的部分和全部相鄰的部分翻轉到左邊、右邊、頂部和所選部分的底部(若是有的話)。
    3. 以如下立場爲例:

      bwbw
      瓦特
      bbwb
      bwwb
      在這裏,「b」表示其黑色一側向上的部分,而「w」表示其白色一側向上的部分。若是咱們選擇從第3行翻轉第1部分(此選擇顯示在圖片中),則字段將成爲:

      bwbw
      bwww
      瓦布
      瓦布
      遊戲的目標是翻轉全部的棋子,白色的一面向上或全部的碎片黑色的一面向上。您將編寫一個程序,該程序將搜索實現此目標所需的最小輪數。

       

       

      1. 那麼首先我用的是BFS解
      2. 2.判重用康拓展開,把狀態轉換成排列序號的來
      1. #include<iostream>
        #include<queue>
        #include<cstring>
        using namespace std;
        typedef struct table {
        int pic[6][6];
        }table;blog

        table start; //初始狀態索引

        int P[16] = { 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768 };
        bool vis[65536]; //狀態數組
        int dist[65536];
        queue<table>Q;
        //黑0 白1
        char Negate(int ch)
        {
        if (ch)
        return 0;
        return 1;
        }遊戲

        void turn(int x, int y, table& T)
        {
        T.pic[x][y] = Negate(T.pic[x][y]); //自身
        T.pic[x][y - 1] = Negate(T.pic[x][y - 1]); //左側
        T.pic[x][y + 1] = Negate(T.pic[x][y + 1]); //右側
        T.pic[x - 1][y] = Negate(T.pic[x - 1][y]); //上側
        T.pic[x + 1][y] = Negate(T.pic[x + 1][y]); //下側
        }圖片

        int get_dec(table T) //位壓縮 
        {
        int dec = 0;
        int s = 0;
        for (int i = 4; i > 0; --i)
        for (int j = 4; j > 0; --j)
        {
        dec += T.pic[i][j] * P[s];
        s++;
        }
        return dec;
        }ci

        int BFS()
        {
        Q.push(start); //初始狀態入隊
        int st = get_dec(start); //獲取索引
        vis[st] = true;
        int front = 1, rear = 2;
        table Now;
        while (front < rear)
        {
        Now = Q.front(); //頭結點出隊
        Q.pop();
        int index = get_dec(Now); //獲取索引
        if (index == 0 || index == 65535) //找到終點
        return front;
        for (int i = 0; i < 16; ++i)
        {
        int x = i / 4 + 1; //橫座標 
        int y = i % 4 + 1; //縱座標
        table Next = Now;
        turn(x, y, Next); //變換求下一步
        int ni = get_dec(Next);
        if (!vis[ni])
        {
        vis[ni] = true;
        Q.push(Next);
        dist[rear] = dist[front] + 1;
        rear++;
        }
        }
        front++;
        }
        return -1;
        }get

        int main() {
        for (int i = 0; i < 6; ++i)
        for (int j = 0; j < 6; ++j)
        start.pic[i][j] = 0;
        memset(vis, 0, sizeof(vis));
        for (int i = 1; i <= 4; ++i)
        for (int j = 1; j <= 4; ++j)
        {
        char ch;
        cin >> ch;
        if (ch == 'w')
        start.pic[i][j] = 0;
        else
        start.pic[i][j] = 1;
        }string

        int s = BFS(); if (s != -1) cout << dist[s] << endl; else cout << "Impossible" << endl; return 0;}

相關文章
相關標籤/搜索