題目描述
在3×3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是:給出一種初始布局(初始狀態)和目標布局(為了使題目簡單,設目標狀態為123804765),找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。
輸入輸入初試狀態,一行九個數字,空格用0表示。
輸出只有一行,該行只有乙個數字,表示從初始狀態到目標狀態需要的最少移動次數(測試資料中無特殊無法到達目標狀態資料)。
樣例輸入
283104765
樣例輸出
4bfs+康拓展開:
dir:每個數字交換的方向(位置)。
zeropos:0的位置,列舉了0的位置再根據交換的方向確定與0交換的那個數字的位置。
numpos:讀入的一維數字的二維座標,也是方面zeropos好計算而設定的。
#include#include#include#includeusing namespace std;
const int dir[4][2]=,,,};
const int zeropos[9][2]=,,,,,,,,};
const int numpos[3][3]=,,};
struct node
list[100010];
bool hash[362890];
int f[9];
int hashs;
char st[10],goal[10];
int kang(char *str) //康拓展開
if (temp==hashs)}}
head++;
}}int main()
dfs+a*:
首先定義乙個dis[10][10]陣列,記錄偏移距離,我們把地圖中的點按行標號,則dis[i][j]表示從第i個點到第j個點至少移動的步數。
舉個例子:
點的編號:1 2 3
4 5 6
7 8 9
那麼顯然dis[1][2]=1,dis[2][9]=3,dis[3][4]=3
這個dis陣列可通過預處理完成,應該是這個樣子:
0 1 2 1 2 3 2 3 4
1 0 1 2 1 2 3 2 3
2 1 0 3 2 1 4 3 2
1 2 3 0 1 2 1 2 3
2 1 2 1 0 1 2 1 2
3 2 1 2 1 0 3 2 1
2 3 4 1 2 3 0 1 2
3 2 3 2 1 2 1 0 1
4 3 2 3 2 1 2 1 0
接著定義乙個p[10]陣列,p[i]表示數字i在目標狀態中的位置,也可以通過預處理完成,
const int p[10]=;
然後定義乙個r[10]陣列,r[i]表示數字i在當前狀態中的位置,這個需要動態維護。
那麼估價函式的值當然就是數字0-8 的偏移量之和了。
#include#include#include#include#includeusing namespace std;
const int dx[5]= ;
const int dy[5]= ;
const int p[10]= ; //p[i]表示數字i在目標狀態中的位置
int s,flag,r[10],a[5][5],map[5][5],dis[10][10]; //r[i]表示數字i在當前狀態中的位置
bool check()
int get()
int jue(int a,int b)
int calx(int i)
int caly(int i)
void dfs(int depth,int x,int y)
for(int i=0; i<4; i++)
}void pre()
int main()
for(s=0;; s++)
} 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 ...