poj 1077 八數碼難題

2021-06-03 01:39:15 字數 1301 閱讀 3926

終於自己ac了這道八數碼難題,用的方法是最最普通的單項bfs+hash,這裡主要的難點在於如何儲存狀態,其實,在八數碼裡所有的狀態共有9!種=362880種,所以在每個轉台節點,我需要乙個char state[3][3]來記錄當前棋盤的狀態,用乙個int x,y來記錄當前x的位置,用char operation來記錄從父狀態到這個狀態需要進行的操作,當然,為了記錄路徑,我需要記錄它的父節點,然而這個父節點要怎麼去記錄呢,剛開始的時候對於這個問題糾結了很久,曾經直接把結構體存在佇列裡面,然後用指標去引用它的父節點,殊不知,當出隊操作後,宣告的節點就是去了意義,所以這種做法是錯誤的。看了別人的思路,把所有的狀態節點都存在乙個結構體陣列裡面,並且用乙個count記錄當錢陣列裡面狀態的個數,因為每出來乙個新狀態,就把它賦值給相應的陣列元素。所以,乙個狀態的父狀態就可以指向父狀態的陣列下表index,到時候可以直接讀取。還有一點需要注意的是進行hash時,不同的max取值可能會導致不同的結果,一般講max取較大的素數,事實證明,用stl  來存狀態去重效率會低很多,用hash的話效率會高一些。對於路徑的尋找,既然知道了每一狀態的操作,則可以從目標狀態開始將操作壓棧,到時候出棧即為正確的從初始態到目標態的操作。

#include#include#include#include#include#include#includeusing namespace std;

#define max 8000003

struct node

allstate[400000];

int hash[max];

//setstateset;

queuequ;

stackpath;

int dirx[4]=;

int diry[4]=;

int gethash(node n)

void getpath(node target)

}void bfs(node head)

int x=allstate[index].x;

int y=allstate[index].y;

for(i=0;i<4;i++)

if(diry[i]==0)

qu.push(statecount);

allstate[statecount++]=newnode;

} }if(!isok)

getpath(outnode);

while(!path.empty())

}} head.parent=-1;

head.operation='0';

bfs(head);

return 0;

}

POJ1077 經典的八數碼問題

很經典的八數碼問題,可以用單向廣度優先搜尋 雙向廣度優先搜尋 a 演算法 ida演算法解。用了雙向廣度優先搜尋和a 演算法解,在用a 演算法時,糾結了好幾天,後來在網上看了乙份部落格才發現自己錯在哪。之後解出來了。雖然做這題時很糾結,不過收穫真的很大,痛而快樂著 下面貼出用雙向廣度優先搜尋和a 演算...

A 搜尋演算法,poj1077 八數碼

今天看了a 搜尋演算法,聽說牛逼的很,不過關鍵還是在於它的評估函式,估計也不一定每題都能這麼容易想吧 就 來說吧,s,儲存所有所搜到的結點的資訊,包括空格位置,深度及評估值,這裡不給出h是因為h一直在變,b儲存開始結點資訊,visited儲存是否訪問到,接下來方向,答案,heap是為了提速而寫的堆實...

poj 1077 Eight A 解八數碼問題

題意 經典的八數碼問題。分析 搜尋演算法的區別是如何重排open表,關鍵是如何編碼狀態和定義狀態的值。對搜尋過程中任意狀態s,a 演算法以g s h s 重排open表,也就是說g s h s 是排列open中狀態的依據,其中g s 是初始狀態到s的消耗,h s 是s到目標狀態的估計。我重排open...