POJ1077 經典的八數碼問題

2021-06-08 07:14:57 字數 2297 閱讀 2495

很經典的八數碼問題,可以用單向廣度優先搜尋、雙向廣度優先搜尋、a*演算法、ida演算法解。

用了雙向廣度優先搜尋和a*演算法解,在用a*演算法時,糾結了好幾天,後來在網上看了乙份部落格才發現自己錯在哪。之後解出來了。雖然做這題時很糾結,不過收穫真的很大,痛而快樂著…………

下面貼出用雙向廣度優先搜尋和a*演算法做的**

//a*演算法

#include #include #include #include using namespace std;

const int maxn=362882;

int n1,n2; //n1記錄正向搜尋的步驟數,n2記錄逆向搜尋的步驟數

int num[10];

int visit1[maxn],visit2[maxn]; //正向搜尋的訪問陣列,逆向搜尋的訪問陣列

int dir[4][2]=,,,};

char dir1[4]=;

char dir2[4]=;

struct node //棋盤狀態結點

s,e;

struct path //路徑

path1[maxn],path2[maxn]; //正向搜尋路徑,逆向搜尋路徑

void swap(int &a,int &b)

bool check(int x,int y)

void init()

else

s.map[i][j]=ch;

}}int calculate(char m[3]) //計算所處的狀態

v+=count*num[a-1];

}return v;

}bool tbfs()

if(!visit1[th])

swap(x,point.x);

swap(y,point.y);

swap(point.map[x][y],point.map[point.x][point.y]);}}

}if(!r.empty())

if(!visit2[th])

swap(x,point.x);

swap(y,point.y);

swap(point.map[x][y],point.map[point.x][point.y]);}}

}}

return false;

}int main()

for(i=k-1;i>=0;i--)

printf("%c",dir1[d[i]]);

while(n2>0)

printf("\n");

}else

printf("unsolvable\n");

return 0;

}

//雙向廣度優先搜尋

#include #include #include #include #include using namespace std;

const int maxn=362882;

int st,end,pre[maxn],a[10];

char path[maxn]; //路徑

bool visit[maxn]; //標誌訪問陣列

int frac[9]=;

struct node

};int hash(int s) //計算所處的狀態

return v;

}int geth(int s) //計算啟發函式值,即曼哈頓距離

return v;

}void astar()

q.push(point1);

while(!q.empty())

}if((point1.x+2)/3!=3) //向下交換

}if(point1.x%3!=1) //向左交換數字

}if(point1.x%3!=0) //向右交換數字}}

}int main()

end=0;

memset(visit,0,sizeof(visit));

astar();

j=0;

while(st!=end)

for(i=j-1;i>=0;i--)

printf("%c",str[i]);

printf("\n");

return 0;

}

poj 1077 八數碼難題

終於自己ac了這道八數碼難題,用的方法是最最普通的單項bfs hash,這裡主要的難點在於如何儲存狀態,其實,在八數碼裡所有的狀態共有9!種 362880種,所以在每個轉台節點,我需要乙個char state 3 3 來記錄當前棋盤的狀態,用乙個int x,y來記錄當前x的位置,用char oper...

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...