wikioi1225 八數碼難題

2021-06-17 15:58:35 字數 1647 閱讀 9323

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來表示。空格周圍的棋子可以移到空格中。要求解的問題是 給出一種初始布局 初始狀態 和目標布局 為了使題...