C STL解決八數碼問題

2021-10-02 13:14:23 字數 2248 閱讀 1875

先放原始碼 大部分借鑑了書本的**

隨後對部分**進行解釋

#include #include #include #define len 362880

using namespace std;

/* * 八數碼問題

* * */

struct node;

int dir[4][2]=,,,};

int vis[len]=;

long int factory=;

int start[9];

int goal[9];

bool cantor(int str,int n)

}res+=con*factory[n-i-1];//被選中的數後面還有幾個數的全排列

}if(!vis[res])

else

}int bfs()}}

return -1;

}int main() ;

這個判重的方法我們就先不談

先解決方向遍歷如何產生新狀態和如何處理舊狀態的問題

新的狀態進來 我們命名a 遍歷了方向後 b c d進來 步數是1

同時a出去

b出去的同時 e f。。。進來

不斷到目標狀態

當然當乙個狀態進入的同時判斷是不是處理過了

處理過了就直接出去

以上的描述 不難看出這個是先進先出表 就是佇列

這個是處理狀態的方法

接下來處理新產生的狀態究竟有沒有被處理過的方法

引入另乙個方法

康托展開是乙個全排列到乙個自然數的雙射,常用於構建雜湊表時的空間壓縮。 康托展開的實質是計算當前排列在所有由小到大全排列中的順序,因此是可逆的。

康托展開舉例

再舉個例子說明。

在 5個數的排列組合中,計算 34152的康托展開值。

首位是3,則小於3的數有兩個,為1和2, ,則首位小於3的所有排列組合為

第二位是4,由於第一位小於4,1、2、3中一定會有1個充當第一位,所以排在4之下的只剩2個,所以其實計算的是在第二位之後小於4的個數。因此 。

第三位是1,則在其之後小於1的數有0個,所以 。

第四位是5,則在其之後小於5的數有1個,為2,所以 。

最後一位就不用計算啦,因為在它之後已經沒有數了,所以 固定為0

根據公式:

以下用cantor表示康托展開

在使用cantor的時候 他有什麼功能 是我們要知道的 而且這個是思想 演算法 需要我們認為去實現的

cantor可以在你給出的序列中計算這個序列在所有可能的排列裡面它是第幾個

那麼利用這個用能我們在乙個新的狀態產生的時候 放入cantor函式中 判斷他是第幾個數 假設是第n個數

那麼我們就讓

vis[n]=1
下次還有新的狀態產生的時候 恰好是第n個數 程式就知道這個狀態已經遇見過了 沒有處理的意義了 就放棄這個狀態去產生另乙個新的狀態

假設數2143

判斷他的cantor值 那麼

1.首位比2小的  只有1 其餘的3個數的全排列就是 1×2×3=6

2.首位是2 的時候 因為要計算這個數是第幾大 只需要計算在這個數前面的有幾個就可以了

首位是2 的時候 第二位比1 小的 沒有 所以是0

3.前面兩位是21的時候 後面兩位比4小的只有3 那麼就是1

4。前面三位是214的時候 最後以為是3 那麼沒有比3 小的數了 就是 0

所以就是6+0+1+0=7

所以cantor值是7

注意的是這裡是cantor值是7並不是第7大的數

因為我們會把vis[7]=1;所以表示cantor是從0開始計算的

所以這個是第8大的數字

不信的話可以自己去寫寫

運用這個思想 就可以寫出cantor函式了

我擷取部分的函式來說明一下

bool cantor(int str,int n)

}res+=con*factory[n-i-1];//被選中的數後面還有幾個數的全排列

}if(!vis[res])

else

}

res計算這個是第幾大的數

con計算當陣列指向某個下位置的時候 比這個位置上的數在後面還要小的有幾個

我們用它來計算全排列 1到10的全排列都放在了factory陣列內

然後if判斷是不是處理過 如果沒有處理過 就處理 判重

處理過了 就return 0

八數碼問題

八數碼問題 一.八數碼問題 八數碼問題也稱為九宮問題。在3 3的棋盤,擺有八個棋子,每個棋子上標有1至8的某一數字,不同棋子上標的數字不相同。棋盤上還有乙個空格,與空格相鄰的棋子可以移到空格中。要求解決的問題是 給出乙個初始狀態和乙個目標狀態,找出一種從初始轉變成目標狀態的移動棋子步數最少的移動步驟...

八數碼問題

2 6 4 1 3 7 0 5 8 8 1 5 7 3 6 4 0 2 樣例輸出 還有就是重判的問題,如何重判呢?第一種方法 把排列變成整數,然後只開乙個一維陣列,也就是說設計一套排列的編碼和解碼函式,把0 8的全排列和0 362879的整數意義一一對應起來。時間效率高,但編碼解碼法適用範圍並不大,...

八數碼問題

八數碼問題 題意 編號為1 8的8個正方形滑塊被擺成3行3列 有乙個格仔留空 如下圖所示 每次可以把與空格相鄰的滑塊 有公共邊才算相鄰 移到空格中,而他原來的位置 就成為了新的空格。如果無法到達目標局面,則輸出 1。2 6 4 13 75 8 移到後 8 1 5 73 642 樣例輸入 2 6 4 ...