路径搜索问题
- 八数码:
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。
空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局
方法一:无脑深度优先搜索+map判重复;
方法二:无脑广度优先搜索判重复;
方法三:双向广度优先搜索;
上面是业余区,下面是专业区
方法四:A* + hash
方法五:IDA* 和上面大同小异
方法六:不知阁下听说过曼哈顿距离吗 没错,用这个。和上面的IDA*结合就好。但是其实忘记这个看起来屌屌的名字,其实就是一个简单的估值函数
好吧,上面3种其实是一种方法
代码区
方法1:都会写,我就不码了 很简单,胡大神亲测30行
方法2:很简单,
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
const int end = 123804765;
void change(int N[],int a)
{
for(int i = 8;i >= 0;i--){
N[i] = a%10;a/=10;
}
}
bool ok(int x,int y){
if(x < 0||x > 2||y<0||y>2) return false;
return true;
}
int ichange(int N[]){
int x = 0;
for(int i = 0;i <= 8;i++)
x = x*10+N[i];
return x;
}
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
map<int,int> M;
struct Node{
int a,t;
};
int search(int a){
int N[10];
queue<Node> Q;
Q.push((Node){a,0});
while(!Q.empty())
{
Node u = Q.front();Q.pop();
change(N,u.a);
int z;
for(int i = 0;i <= 8;i++)
if(N[i] == 0) z = i;
int x = z/3;int y = z%3;
for(int i = 0;i < 4;i++){
int newx = x+dx[i];
int newy = y+dy[i];
if(ok(newx,newy)){
swap(N[x*3+y],N[newx*3+newy]);
int m = ichange(N);
if(!M.count(m)){
M[m] = u.t+1;
Q.push((Node){m,u.t+1});
}
swap(N[x*3+y],N[newx*3+newy]);
}
}
if(M.count(end)) return M[end];
}
}
int main(){
int a;
scanf("%d",&a);
int ans = search(a);
if(ans == -1) printf("NO Way\n");
else printf("%d\n",ans);
return 0;
}
方法3:和广搜差不多,没什么代表性;

浙公网安备 33010602011771号