现在的位置: 首页 > 综合 > 正文

HDU 1043 Eight

2013年10月29日 ⁄ 综合 ⁄ 共 1482字 ⁄ 字号 评论关闭
#include<iostream>  
#include<queue>  
#include<string>  
using namespace std;  
#define N 10  
#define MAX 362881 //最多可能有9!个排列  
int fac[]={1,1,2,6,24,120,720,5040,40320,362880};//康托展开数列  
bool visited[MAX];   
string route[MAX];  

int move1[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; // 上 下 左 右 ,因为是逆序查找 所以对应下面为 下 上 右 左,如change数组  
char change[5]="durl";  

int cantor(int s[])//康托判重  
{    int sum=0;  
for(int i=0;i<9;i++)  
{  
	int num=0;   
	for(int j=i+1;j<9;j++)  
		s[j]<s[i]?num++:1;  
	sum=sum+(num*fac[8-i]);  
}  
return sum+1;  
}  

typedef struct eight{  
	int p[N];  
	int now,position;//now 为当前‘x’所在的位置(0-8),position为在排列中的序列号  
	string route; //从终点到起点的路程  

}link;  

void bfs()  
{  
	int i;  
	queue<link> q;  
	link first,second;  
	for(i=0;i<8;i++) //设终点为 123456780 
		first.p[i]=i+1;  
	first.p[i]=0,first.now=8,first.position=cantor(first.p);  
	first.route="";  
	route[first.position]="";  
	q.push(first);  
	visited[first.position]=true;  

	while(!q.empty())  
	{  
		first=q.front();  
		q.pop();  
		for(i=0;i<4;i++)  
		{  
			int x=first.now/3+move1[i][0];  
			int y=first.now%3+move1[i][1];  
			if(x<0 || x>2 || y <0 || y>2)  
				continue;  
			second=first,second.now=x*3+y;  
			second.p[first.now]=second.p[second.now];  
			second.p[second.now]=0;  
			second.position=cantor(second.p);  
			if(!visited[second.position])//判断是否到过  
			{  
				second.route+=change[i];  
				visited[second.position]=true;  
				route[second.position]=second.route;  
				q.push(second);  
			}  
		}  
	}  
}  
void ouput(int k)  
{         
	if(!visited[k])  
	{  
		cout<<"unsolvable"<<endl;  
		return ;  
	}  

	for(int i=route[k].size()-1;i>=0;i--)//逆序输出  
		cout<<route[k][i];  
	cout<<endl;  
}  
int main()  
{  
	bfs();  
	int p[N];  
	char c;  
	while(cin>>c)  
	{  
		int i=0;  
		c=='x'?p[i]=0:p[i]=c-'0';  
		for(i=1;i<9;i++)  
			cin>>c,c=='x'?p[i]=0:p[i]=c-'0';  
		int k=cantor(p);  
		ouput(k);                 
	}  
}  

抱歉!评论已关闭.