yours和zero在研究a*啟發式演算法.拿到一道經典的a*問題,但是他們不會做,請你幫他們.問題描述
在3×3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是:給出一種初始布局(初始狀態)和目標布局(為了使題目簡單,設目標狀態為123804765),找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。
輸入初試狀態,一行九個數字,空格用0表示
只有一行,該行只有乙個數字,表示從初始狀態到目標狀態需要的最少移動次數(測試資料中無特殊無法到達目標狀態資料)
283104765
4
初始狀態經過一步生成新的狀態,這些狀態又經過一步生成新的狀態,就這樣生成下去,總會找到目標狀態,而且是最少次數的,因為我們每一次都會把x步能走的的找完,沒有就檢視x+1步的。這就是bfs。
當乙個狀態1生成狀態2之後,狀態2又可能生成狀態1,狀態1又生成狀態2,產生了死迴圈,所以需要判重,我用了康托展開。
#include #include const int b[4]=;
struct node
d[555555]; //佇列
char s[10];
bool hash[400000]=; //hash
int e_t[10]=,tmp[10]; //目標狀態,臨時變數
long jst(int n) //求階乘
long kto(int s) //康拓展開
; for(int i=1;i<=8;i++)
return hs+1; //康拓展開的規則,最後一定要加1}
bool flag(int a,int b)
int main()
d[1].ans=0;
hash[kto(tmp)]=1;
long head=1,tail=1; //佇列初始化
int b;bool flag;
while(head<=tail)
//找0的位置
if(!flag(b,b[i])) continue; //是否越界
int t=tmp[b];tmp[b]=tmp[b+b[i]];tmp[b+b[i]]=t; //移動
flag=0;
for(int j=1;j<=9;j++)
if(tmp[j]!=e_t[j])
//判斷是否到達目標狀態
if(!flag) break;
long hs=kto(tmp);
if(hash[hs]==0) //判重
t=tmp[b];tmp[b]=tmp[b+b[i]];tmp[b+b[i]]=t; //換回來供他人使用
}head++;
if(!flag) break;
} printf("%ld\n",d[head].ans+1);
return 0;
}
1225 八數碼難題
時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題解檢視執行結果 description yours和zero在研究a 啟發式演算法.拿到一道經典的a 問題,但是他們不會做,請你幫他們.問題描述 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留...
1225 八數碼難題
題目描述 description yours和zero在研究a 啟發式演算法.拿到一道經典的a 問題,但是他們不會做,請你幫他們.問題描述 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布...
CodeVs 1225 八數碼難題
yours和zero在研究a 啟發式演算法.拿到一道經典的a 問題,但是他們不會做,請你幫他們.問題描述 在3 3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布局 初始狀態 和目標布局 為了使題...