POJ 1077 Eight bfs

        这题一开始做,什么优化都没做, 直接MLM+TLM, 后来用了康托展开+双向bfs过了,注意这题答案不唯一,开始与sample给的例子不同,以为自己错了,后来发现两个都对,果断交上去,结果AC掉了~

#include <iostream>

#include <string>

#include <queue>

#include <memory.h>

using namespace std;



struct status

{

	int x_x, x_y;

	int a;

	string path;

};

int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};

int isvisit[362880];

string path[362880];

char oper_name[] = {'u','d','l','r'};

char opposite_oper[] = {'d', 'u', 'r', 'l'};



bool do_operate(int, const status&, status&);

void bfs();

bool is_goal(const status&);

int encode(int);



int start;

int goal = 123456789;

int x_x, x_y;



int main()

{

	char c;

	

	int tmp[9];

	memset(isvisit, false, sizeof(isvisit));  



	while (cin >> c)

	{



		for (int i = 0; i < 3; i++)

			for (int j = 0; j < 3; j++)

			{		

				if (c == 'x')

				{

					tmp[3*i+j] = 9;

					x_x = i;

					x_y = j;

				}

				else

					tmp[3*i+j] = c - '0';

				if (!(i == 2 && j == 2))

					cin >> c;

			}

		start = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8];

		bfs();

		memset(isvisit, false, sizeof(isvisit));  

	}

	return 0;

}



void bfs()

{

	queue<status> Q1, Q2;

	bool flag;

	status p, next;

	p.a = start;

	p.path = "";

	p.x_x = x_x;

	p.x_y = x_y;

	int code;

	isvisit[encode(p.a)] = 1;

	Q1.push(p);



	p.a = goal;

	p.x_x = 2;

	p.x_y = 2;

	isvisit[encode(p.a)] = 2;

	Q2.push(p);

	while (!Q1.empty())

	{

		p = Q1.front();

		Q1.pop();



		if (p.a == goal)

		{

			cout << p.path << endl;

			return ;

		}



		for (int i = 0; i < 4; i++)

		{

			flag = do_operate(i, p, next);

			next.path = p.path + oper_name[i];

			code = encode(next.a);

			if (flag )

			{

				if (isvisit[code] == 0)

				{

			    	isvisit[code] = 1;

					path[code] = next.path;

				    Q1.push(next);

				}

				else if (isvisit[code] == 2)

				{

					cout << next.path << path[code] << endl;

					return;

				}

			}

		}



		p = Q2.front();

		Q2.pop();



		for (int i = 0; i < 4; i++)

		{

			flag = do_operate(i, p, next);

			next.path = opposite_oper[i]+p.path;

			code = encode(next.a);

			if (flag)

			{

				if (isvisit[code] == 0)

				{

					isvisit[code] = 2;

					path[code] = next.path;

					Q2.push(next);

				}

				else if (isvisit[code] == 1)

				{

					cout <<  path[code]  << next.path << endl;

					return;

				}

			}

		}



	}



	cout << "unsolvable" << endl;



}



bool do_operate(int mode, const status& p, status & s)

{

	s = p;

	int num = p.a;

	int tmp[9];



	for (int i = 8; i >= 0; i--)

	{

		tmp[i] = num%10;

		num /= 10;

	}



	switch (mode)

	{

	case 0:

		if (p.x_x > 0)

		{

			swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x-1) + s.x_y]);

			s.x_x = s.x_x-1;

			s.x_y = s.x_y;

			s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8];

		}

		else

			return false;

		break;

	case 1:

		if (p.x_x < 2)

		{

			swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x+1) + s.x_y]);

		    s.x_x = p.x_x+1;

			s.x_y = p.x_y;

			s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8];

		}

		else

			return false;

		break;

	case 2:

		if (p.x_y > 0)

		{

			swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x) + s.x_y-1]);

			s.x_x = p.x_x;

			s.x_y = p.x_y-1;

			s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8];

		}

		else

			return false;

		break;

	case 3:

		if (p.x_y < 2)

		{

			swap(tmp[3*s.x_x + s.x_y],tmp[3*(s.x_x) + s.x_y+1]);

			s.x_x = p.x_x;

			s.x_y = p.x_y+1;

			s.a = tmp[0]*1e8 + tmp[1]*1e7 + tmp[2]*1e6 + tmp[3]*1e5 + tmp[4]*1e4 + tmp[5]*1e3 + tmp[6]*1e2 + tmp[7]*10 + tmp[8];

		}

		else

			return false;

		break;

	}



	return true;

}





int encode(int num)

{

	int tmp[9];

	int cnt;



	for (int i = 8; i >= 0; i--)

	{

		tmp[i] = num%10;

		num /= 10;

	}



	for (int i = 0; i < 9; i++)

	{

		cnt = 0;

		for (int j = i+1; j < 9; j++)

			if (tmp[i] > tmp[j]) cnt++;



		num += cnt*fact[8-i];

	}



	return num;

}

你可能感兴趣的:(poj)