10085UVA最远的状态

也是和例题几乎一样~

#include<stdio.h>
#include<string.h>
typedef int State[9];
const int maxstate=1000000;
const int dx[]={-1,1,0,0};
const int dy[]={0,0,1,-1};
char dir[]={'U','D','R','L'};
State que[maxstate];
int fa[maxstate];
int op[maxstate];
const int maxhash = 100000;
int next[maxstate];
int head[maxhash];
int hash(State& s)
{
	int v=0;
	for(int i=0;i < 9;i++)
	{
		v=v*10+s[i];
	}
	return v%maxhash;
}
bool tryinsert(int id) //id in que
{
	int h=hash(que[id]);
	int u=head[h];
	while(u)
	{
		if(0==memcmp(&que[u],&que[id],sizeof(State)))
			return false;
		u=next[u];
	}
	next[id]=head[h];
	head[h]=id;
	return true;
}
int bfs() //return pos in que
{
	//initialize head array to store pos in que
	memset(head,0,sizeof(head));

	int front,rear;
	front=1,rear=2;
	while(front<rear)
	{
		State& s= que[front]; //take a 'state' out
		int x,y,z;
		for(z=0; z<9;z++)
			if(!s[z])
				break;
		x = z/3;
		y = z%3;
		int nx,ny,nz;
		for(int i=0;i < 4;i++)
		{
			nx=x+dx[i];
			ny=y+dy[i];
			if(nx>=0 && ny>=0 && nx<3 && ny<3)
			{
				nz=nx*3+ny;
				State& t=que[rear];
				memcpy(&t,&s,sizeof(State));
				t[nz]=s[z];
				t[z]=s[nz];
				fa[rear]=front;
				op[rear]=i;
				if(tryinsert(rear))
					rear++;
			}
		}
		front++;
		//
		//printf("~%d %d\n",front,rear);
	}
	return front-1;
}
void print(int id)
{
	if(fa[id]!=id)
	{
		print(fa[id]);
		putchar(dir[op[id]]);
	}
}
int main()
{
	//
	freopen("input.txt","r",stdin);
	freopen("out.txt","w",stdout);

	int t;
	scanf("%d",&t);
	for(int numcase=1;numcase <= t;numcase++)
	{
		memset(fa,0,sizeof(fa));
		memset(op,0,sizeof(op));
		for(int i=0;i < 9;i++)
		{
			scanf("%d",&que[1][i]);
		}
		fa[1]=1;
		op[1]=0;

		int end=bfs();
		printf("Puzzle #%d\n",numcase);
		for(int i=0;i<3;i++)
		{
			printf("%d",que[end][i*3]);
			for(int j=1;j<3;j++)
			{
				printf(" %d",que[end][i*3+j]);
			}
			putchar(10);
		}
		print(end);
		putchar(10);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值