歡迎使用CSDN markdown編輯器

2021-08-04 10:33:15 字數 1943 閱讀 7141

題目描述[八數碼問題]

八數碼問題,即在乙個3×3的矩陣中有8個數(1至8)和乙個空格,現在要你從乙個狀態轉換到另乙個狀態,每次只能移動與空格相鄰的乙個數字到空格當中,問題是要你求從初始狀態移動到目標狀態所需的最少步數。如下圖所示。

1 2 31

2 3

8 0 47

8 4

7 6 50

6 5

初始狀態 目標狀態

如上圖所示的資料以矩陣形式給出。現在給出分別代表初始狀態和目標狀態的兩個3*3的矩陣,請給出兩個矩陣相互轉化的最少步數。

輸入 第1行-第3行:3個用空格分隔的整數,代表初始狀態相應位置的數字,0代表空格

第4行-第6行:3個用空格分隔的整數,代表終止狀態相應位置的數字,0代表空格

輸出 第1行:乙個整數,最小轉換步數,如不能到相互轉化則輸出」impossible」

樣例輸入

1 2 3

8 0 4

7 6 5

1 2 3

7 8 4

0 6 5

樣例輸出

2 思路:此題為典型的廣度搜尋,由於狀態較多,因此如何解決判重問題極為重要,可利用dbfs來減小時間複雜度。

判重:採用排列組合的方式,將八數碼的九格換成九位數,共有9!種排列方式,由小到大排列,找到他的所處位置

雜湊判重:運用雜湊表,雜湊鏈,每乙個八數碼狀態對應乙個編號,取乙個恰當的mod數,利用鏈式處理衝途

採用優先佇列,先判斷 f=g+h,f代表到目標狀態差值,g代表不相同的各數,h代表第幾步了,f越小,越靠近目標

#include

#include

#include

#include

#include

#include

using namespace std;

const int hashsize=100003;

struct node

};struct hashlist

;hashlist *(hl[100003]);

priority_queueq;

int dx[4]=;

int dy[4]=;

node goal;

node star;

int jop1(int

s[9])

total+=cnt;

}return total%2;

}int judge(int bh)

else

p=new hashlist;

p->next=hl[temp];

hl[temp]=p;

return

1; }

}int bianhao(int

s[9])

int df(int

s[9])

return

8-cnt;

}int bfs()//廣度搜尋

}int

x=z/3;

inty=z%3;

int newx=x+dx[i];

int newy=y+dy[i];

if(newx>=0&&newx<3&&newy>=0&&newy<3)

*/if(memcmp(n.state,goal.state,9

*sizeof(int))==0) return n.step;

q.push(nn);}}

}}

}return -1;

}int main()

for(int j=0;j<9;j++) scanf("%d",&goal.state[j]);

if(jop1(star.state)^jop1(goal.state))

int flag=bfs();

if(flag!=-1) printf("%d\n",flag);

}

歡迎使用CSDN markdow

本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...

歡迎毛毛與妞妞使用CSDN markdown編輯器

建立乙個自定義列表 如何建立乙個註腳 注釋也是必不可少的 katex數學公式 新的甘特圖功能,豐富你的文章 uml 圖表 flowchart流程圖 匯出與匯入 你好!這是你第一次使用markdown編輯器所展示的歡迎頁。如果你想學習如何使用markdown編輯器,可以仔細閱讀這篇文章,了解一下mar...

歡迎使用CSDN markdow1n編輯器

本markdown編輯器使用stackedit修改而來,用它寫部落格,將會帶來全新的體驗哦 markdown 是一種輕量級標記語言,它允許人們使用易讀易寫的純文字格式編寫文件,然後轉換成格式豐富的html頁面。維基百科 使用簡單的符號標識不同的標題,將某些文字標記為粗體或者斜體,建立乙個鏈結等,詳細...