HDU Eight (2) A* IDA*都是浮云啊。。

http://acm.hdu.edu.cn/showproblem.php?pid=1043

一个事关人生完不完整得题目,自然就要反复多写几遍才能体会其中的精华咯,哈哈。今天又看到了一个用单广的写法,于是乎觉得很好,就自己又写了一遍,没想到109ms。。 Orz。。 连自己都不敢相信哈!! 神马A*、IDA*,都是浮云啊。 

这里简单说思路吧: 从终点开始,预处理出终点能到达的状态(这里终点能达到的状态一定是能达到终点的状态),采用逆向搜索的方法,记录下每种状态达到终点状态的下一个KT值和达到方式,这样在任意读入的一个状态下,只要先判断是否能达,若能达,按照pre数组打出每个方式即可。 没牛的一种思路。。


代码:

/*
HDU 1043 Eight
Tips:单广搜
Runtime : 109ms 
*/ 
#include<stdio.h>
#include<string.h>
#include<queue>
#define MAX 362900
using namespace std;
struct Node{
	char maze[4][4] ;
	int sx,sy ;	
}sta[MAX];
queue<Node> q;
int pre[MAX];
char way[MAX];
bool vis[MAX];
int fac[9] = {1,1,2,6,24,120,720,5040,40320} ;
int dir_x[4] = {0,0,1,-1} ;
int dir_y[4] = {1,-1,0,0} ;
char dir_w[4] = {'l','r','u','d'} ;		// !!!这里的方向和上面的方向数组时相反的; 

//求一个排列的KT 
int get_cat(Node a){
	int num[10],index=0;
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			if(a.maze[i][j] == 'x'){
				num[index++] = 9 ;	
			}
			else
				num[index++] = a.maze[i][j] - '0' ;
		}	
	}
	int res = 0 ;
	for(int i=0;i<9;i++){
		int t= 0 ;
		for(int j=i+1;j<9;j++){
			if(num[i] > num[j])	t++;
		}
		res = res + fac[8-i]*t ;
	}
	return res ;
}
//逆向建立可达状态的路径。 
void bfs(){
	Node a; 
	int num = 1 ,cat;
	for(int i=1;i<=3;i++){
		for(int j=1;j<=3;j++){
			if(i==3 && j==3){	a.maze[i][j] = 'x' ;a.sx = i; a.sy = j ; }
			else {a.maze[i][j] = num + '0' ; num++ ;}	
		}	
	}
	while(!q.empty())	q.pop();
	q.push(a) ;
	memset(pre,-1,sizeof(pre));
	memset(vis,false,sizeof(vis));
	cat = get_cat(a);
	vis[cat] = true ;
	pre[cat] = -2 ;
	while(!q.empty()){
		Node now = q.front();	q.pop();
		int s_x = now.sx ,s_y = now.sy ;
		for(int i=0;i<4;i++){
			Node next = now;
			int n_x = s_x + dir_x[i] ;
			int n_y = s_y + dir_y[i] ;
			if(n_x<1 || n_x>3 || n_y<1 || n_y>3)	continue ;
			char temp = next.maze[s_x][s_y] ;
			next.maze[s_x][s_y] = next.maze[n_x][n_y] ;
			next.maze[n_x][n_y] = temp ;
			next.sx = n_x ;next.sy = n_y ;
			cat = get_cat(next) ;
			if(vis[cat]){
				continue ;	
			}
			else{
				pre[cat] = get_cat(now) ;	
				way[cat] = dir_w[i] ;
				q.push(next) ;
				vis[cat] = true ; 
			}
		}
	}
}

int main()
{
	Node start ;
	char ss[3] ;
	bfs();
	while(scanf("%s",ss)!=EOF){	
		start.maze[1][1] = ss[0] ;
		if(ss[0] == 'x'){
			start.sx = 1 ; start.sy = 1 ;
		}
		scanf("%s",ss);	start.maze[1][2] = ss[0] ;
		if(ss[0] == 'x'){
			start.sx = 1 ; start.sy = 2 ;
		}
		scanf("%s",ss);	start.maze[1][3] = ss[0] ;
		if(ss[0] == 'x'){
			start.sx = 1 ; start.sy = 3 ;
		}
		for(int i=2;i<=3;i++){
			for(int j=1;j<=3;j++){
				scanf("%s",ss);
				start.maze[i][j] = ss[0] ;
				if(ss[0] == 'x'){
					start.sx = i ;start.sy = j ;	
				} 	
			}
		}
		int cat = get_cat(start) ;
		if(pre[cat] == -1){
			printf("unsolvable\n");	
		}
		else if(pre[cat] == -2){
			printf("\n");
		}
		else{
			int now_c ,pre_c ;
			pre_c = cat ; now_c;
			while(pre[pre_c]!=-2){		//打印路径即可。 
				printf("%c",way[pre_c]);		
				pre_c = pre[pre_c] ;
			}	
			printf("\n");
		}
	}
	return 0;	
}


你可能感兴趣的:(HDU Eight (2) A* IDA*都是浮云啊。。)