UVa 10085-The most distant state(BFS,Eight).cpp

八数码问题,参见lrj程序

#include <stdio.h>
 #include <stdlib.h>
 #include <math.h>
 #include <string.h>
 #include <stack>
 #include <queue>
 #include <iostream>
 #include <algorithm>
 
 using namespace std;
 
 #define MAXN  500000
 #define INF 1e8
 #define NEGINF -1e8
 
 int final[9];
 int dx[] = {-1,1,0,0},dy[] = {0,0,-1,1};
 int st[MAXN][9];
 int fa[MAXN];
 char dir[MAXN];
 const int HASHSIZE = 1000003;
 int head[HASHSIZE], next[MAXN];
 int dis[MAXN];
 int maxDis,pos;
 
 typedef int State[9];
 
 void init_lookup_table() { memset(head, 0, sizeof(head)); }
 
 inline int hash(State &s) {
 	int v = 0;
 	for( int i = 0; i < 9; i++ ) {
 
 		v = v * 10 + s[i];
 	}
 	return v % HASHSIZE;
 
 }
 
 int try_to_insert(int s) {
   int h = hash(st[s]);
   int u = head[h];
   while(u) {
     if(memcmp(st[u], st[s], sizeof(st[s])) == 0) return 0;
     u = next[u];
   }
   next[s] = head[h];
   head[h] = s;
   return 1;
 }
 
 
 void bfs() {
 	init_lookup_table();
 	dis[0] = 0;
 	int i,j;
 	int front = 0,rear = 1;				
 	while( front < rear) {
 		State& u = st[front];
 		if( dis[front] >= maxDis ) {
 			maxDis = dis[front];
 			memcpy(final,u,sizeof(final));
 			pos = front;
 		}
 		
 		int a;
 		for( i = 0; i < 9; i++ )
 			if( u[i] == 0 ) {
 				a = i;
 				break;
 			}
 		
 		int b = a % 3; a /= 3;
 		int x,y;
 		for( i = 0; i < 4; i++ ) {
 			x = a + dx[i];
 			y = b + dy[i];
 			if( x >= 0 && x < 3 && y >= 0 && y < 3 ) {
 				State& v = st[rear];
 				memcpy(v,u,sizeof(u));
 				v[3*a + b] = u[3*x + y];
 				v[3*x+y] = 0;				
 				if(try_to_insert(rear)) {
 					if( i == 0 ) dir[rear] = 'U';
 					if( i == 1 ) dir[rear] = 'D';
 					if( i == 2 ) dir[rear] = 'L';
 					if( i == 3 ) dir[rear] = 'R';
 					fa[rear] = front;
 					dis[rear] = dis[front] + 1;
 					rear++;
 				}
 			}
 		}
 		front++;
 	}
 
 }
 
 void printInfo(int s) {
 	if( fa[s] != s )
 		printInfo(fa[s]);
 	else
 		return;
 	printf("%c",dir[s]);
 }
 int main() {
 	#ifndef ONLINE_JUDGE
 		freopen("data.in","r",stdin);
 		//freopen("data.out","w",stdout);
 	#endif
 	
 	int ncase;
 	int i,j,k;
 	char str[100];
 	scanf("%d",&ncase);
 	for( i= 1; i <= ncase; i++ ) {
 		for( j = 0; j < 9; j++ )
 			scanf("%d",&st[0][j]);
 		fa[0] = 0;
 		maxDis = NEGINF;
 		bfs();
 		//printf("%d\n",maxDis);
 		printf("Puzzle #%d\n",i);
 		for( j = 0; j < 3; j ++ ) {
 			bool first = true;
 			for( k = 0; k < 3; k++) {
 				if( first ) {
 					printf("%d",final[j*3+k]);
 					first = false;
 				}
 				else
 					printf(" %d",final[j*3+k]);
 					
 			}
 			printf("\n");
 		}
 		printInfo(pos);
 		printf("\n\n");
 
 		
 	}
 
 	return 0;
 }
 
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值