sun's Blog

Happy coding

poj 1077

#include <iostream>
#include <fstream>
#include <queue>
using namespace std;
#define MAXNUM  362885            //状态共有9!=362880种,数组稍微开大点
struct State
{
	int nine[9];   //用一个九位数组保存状态,空格位置为0
	int number;   //记录对应的逆序数
	int pos; //记录空格位置
};

int hash[MAXNUM]; //hash数组
char path[MAXNUM];

int multi[]={1,1,2,6,24,120,720,5040,40320,362880};//阶乘
int reversedNum(int data[])
//求逆序数,用变进制表示,返回变进制数
{
	int sum=0,i,j;
	for(i=0;i<9;i++)  //求逆序
	{
		int count=0;
		for(j=0;j<i;j++)
			if(data[j]>data[i]) count++;
		sum+=multi[i]*count;
	}
	return sum;
}

bool compare(State a,State b)
{
	if(a.number==b.number) return 1;
	return 0;
}

bool BFS(State start,State end)
//反向BFS
{
	int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//u,d,l,r
	char movement[5]="udlr";

	memset(hash,0,sizeof(hash));
	hash[start.number]=1;

	queue<State> open;  //搜索队列
	State cur,next;
	open.push(start);
	int x,y;
	while(!open.empty())
	{
		cur=open.front();
		open.pop();
		if(compare(end,cur)) return 1;
		for(int i=0;i<4;i++)  //四种状态
		{
			x=cur.pos/3+move[i][0];
			y=cur.pos%3+move[i][1];
			if(x<0||x>2||y<0||y>2) continue; //越界
			next=cur;
			next.pos=3*x+y;
			next.nine[cur.pos]=next.nine[next.pos];
			next.nine[next.pos]=0;
			next.number=reversedNum(next.nine);
			if(!hash[next.number])
			{
				open.push(next);
				path[next.number]=movement[i];
				hash[next.number]=cur.number;
			}
		}
	}
	return 0;
}			
					
int main()
{
	ifstream cin("test.txt");
	State end={{1,2,3,4,5,6,7,8,0},322560,8}; //结束位置设定为 12345678x	
	State start;
	char input;
	while(cin>>input)
	{
		if(input=='x') 	
		{
			start.nine[0]=0;
			start.pos=0;
		}
		else start.nine[0]=input-'0';
		for(int i=1;i<9;i++)
		{
			cin>>input;
			if(input=='x') 
			{
				start.nine[i]=0;
				start.pos=i;
			}
			else start.nine[i]=input-'0';
		}

		start.number=reversedNum(start.nine);

		if(BFS(start,end))
		{
			int index=end.number;
			char stack[MAXNUM];
			int top=0;
			while(index!=start.number)
			{
				stack[top++]=path[index];
				index=hash[index];
			}
			for(int i=top-1;i>=0;i--)
				cout<<stack[i];
			cout<<endl;
		}
		else cout<<"unsolvable\n";
	}
}