路径搜索问题

  1. 八数码:

在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:和广搜差不多,没什么代表性;

posted @ 2017-04-23 17:34  rsqppp  阅读(179)  评论(0)    收藏  举报