洛谷 八數碼難題 BFS 啟發式(IDA

2021-08-28 16:57:01 字數 2160 閱讀 9073

初見安~這裡是傳送門:洛谷p1379。

在3×3的棋盤上,擺有八個棋子,每個棋子上標有1至8的某一數字。棋盤中留有乙個空格,空格用0來表示。空格周圍的棋子可以移到空格中。要求解的問題是:給出一種初始布局(初始狀態)和目標布局(為了使題目簡單,設目標狀態為123804765),找到一種最少步驟的移動方法,實現從初始布局到目標布局的轉變。

輸入初始狀態,一行九個數字,空格用0表示

只有一行,該行只有乙個數字,表示從初始狀態到目標狀態需要的最少移動次數(測試資料中無特殊無法到達目標狀態資料)

283104765
4
用bfs來做,過程為交換『0』和上下左右任意方向的數字,直到拼出目標狀態。就挺有bfs「不撞南牆不回頭」的理念。大致思路是很簡單的。

在儲存和設定變數上,為了對比目標狀態,我們可以為走的每一步後的狀態——二維陣列,開乙個結構體並重定向「==」。但依據bfs的搜尋套路,需要乙個vis來記錄是否走過這一步——即這個狀態是否湊出來過。我們可以選擇在結構體裡順便標乙個號,or用乙個set集合去重——但set會有乙個內部的自動排序,所以我們還要重定向乙個「<」or">"(因為我們實際上用不到)

**如下——

#include

using

namespace std;

int sa,sb;

int dir[4]

[2]=

,,,}

;boolin(

int a,

int b)

//檢查是否越界

struct node

return

false;}

bool

operator==(

const node &x)

const

return

true;}

}from,to;

intbfs()

}}}return-1

;}intmain()

} to.a[0]

[0]=

1;//直接賦值

to.a[0]

[1]=

2;to.a[0]

[2]=

3;to.a[1]

[0]=

8;to.a[1]

[1]=

0;to.a[1]

[2]=

4;to.a[2]

[0]=

7;to.a[2]

[1]=

6;to.a[2]

[2]=

5;cout<<

bfs(

)

}

#include

using

namespace std;

int ans[4]

[4]=

,,,}

;int dir[4]

[2]=

,,,}

;//dir並不是隨便的順序哦

int a[4]

[4], k =0;

char s;

bool judge =

false

;bool

check()

//判定是否已經達到了目標狀態

boolin(

int x,

int y)

//越界判定

bool

test

(int now)

//估價函式

//估價不滿足了

return1;

//估價滿足條件,這個位置合法

}void

a_star

(int now,

int x,

int y,

int pre)

if(judge)

return

;for

(int i =

0; i <

4; i++)}

intmain()

if(check()

)//特殊預判

while

(++k)

}}

這樣一來總共耗時300+ms,優化了很多很多。

八數碼真的是乙個非常經典的題目哇!!!

迎評:)

——end——

八數碼問題 啟發式搜尋

一 問題描述 在乙個3 3 的方棋盤上放置著 1,2,3,4,5,6,7,8 八個數碼 每個數碼佔一格 且有乙個空格。這些數碼可以在棋盤上移動,其移動規則是 與空格相鄰的數碼方格可以移入空格。現在的問題是 對於指定的初始棋局和目標棋局,給出數碼的移動序列。該問題稱八數碼難題或者重排九宮問題。原始碼 ...

八數碼問題 啟發式搜尋

我們在搜尋的時候往往會發現一些資料會導致我們的普通的深搜與廣搜都無法通過,那這個時候我們就需要讓起點與終點建立一些聯絡,今天我們講述的啟發式搜尋就是在廣度優先搜尋的基礎上加了這樣乙個優化,叫做估價函式。對於乙個狀態,在我們知道終點狀態的時候,我們可以設計乙個估價函式使我們對這個狀態距離終點的距離有個...

A 啟發式搜尋 八數碼問題

a 啟發式搜尋 include iostream include stdlib.h include conio.h include include define size 3 using namespace std 定義二維陣列來儲存資料表示某乙個特定狀態 typedef int status si...