sicily 1150 简单魔板 & 1151 魔板 bfs

典型的bfs, 第一个是自己写的没有做任何优化,需要8^8的空间保存状态
后来看了别人解题报告,学会了康托展开,全排列压缩,只需要8!空间
 
#include <iostream>

#include <string>

#include <queue>

#include <memory.h>

using namespace std;



struct my_status

{

	int a[2][4];

	string path;



	my_status(){}



	my_status(int a[2][4])

	{

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

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

				this->a[i][j] = a[i][j];

		path = "";

	}



	my_status& operator=(const my_status& item)

	{

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

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

				a[i][j] = item.a[i][j];

		path = item.path;

		return *this;

	}



	bool operator== (const my_status& item)

	{

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

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

				if (a[i][j] != item.a[i][j])

					return false;



		return true;

	}

};



bool isvisit[8][8][8][8][8][8][8][8];

int max_step;

int goal_status[2][4];

int inite_statue[2][4] = {{1,2,3,4}, {8,7,6,5}};



my_status do_operate(int, const my_status&);



void bfs();



int main()

{

	while (cin >> max_step && max_step != -1)

	{

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



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

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

				cin >> goal_status[i][j];

		bfs();

	}

	return 0;

}



void bfs()

{

	my_status p,next_status;



	queue<my_status> Q;

	char c;

	Q.push(inite_statue);



	while (!Q.empty())

	{

		p = Q.front();

		Q.pop();



		if (p.path.size() > max_step)

		{

			cout << "-1" << endl;

			return;

		}

		if (p == goal_status)

		{

			cout << p.path.size() << " " << p.path << endl;

			return;

		}



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

		{

			next_status = do_operate(i, p);

			c = 'A'+i;

			next_status.path = p.path + c;



			if (!isvisit[next_status.a[0][0]-1][next_status.a[0][1]-1][next_status.a[0][2]-1][next_status.a[0][3]-1][next_status.a[1][0]-1][next_status.a[1][1]-1][next_status.a[1][2]-1][next_status.a[1][3]-1])

			{

				isvisit[next_status.a[0][0]-1][next_status.a[0][1]-1][next_status.a[0][2]-1][next_status.a[0][3]-1][next_status.a[1][0]-1][next_status.a[1][1]-1][next_status.a[1][2]-1][next_status.a[1][3]-1] = true;

				Q.push(next_status);

			}

		}



	}

}



my_status do_operate(int mode, const my_status& p)

{

	my_status tmp;

	switch (mode)

	{

	case 0:

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

		{

			tmp.a[0][i] = p.a[1][i];

			tmp.a[1][i] = p.a[0][i];

		}		

		break;

	case 1:

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

		{

			tmp.a[0][i] = p.a[0][i-1];

			tmp.a[1][i] = p.a[1][i-1];

		}

		tmp.a[0][0] = p.a[0][3];

		tmp.a[1][0] = p.a[1][3];

		break;

	case 2:

		tmp = p;

		tmp.a[0][1] = p.a[1][1];

		tmp.a[0][2] = p.a[0][1];

		tmp.a[1][1] = p.a[1][2];

		tmp.a[1][2] = p.a[0][2];

		break;

	}



	return tmp;

}
 
康托展开
#include <iostream>

#include <string>

#include <queue>

#include <memory.h>

using namespace std;



struct my_status

{

	int a;

	string path;

};



int fact[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; //8!的阶乘表



bool isvisit[50000];

int max_step;

int goal_status;

int inite_statue = 12348765;

int do_operate(int, int);



//康托状态压缩

//把需要8^8的储存空间压缩成只需8!空间

//只有8!有效

int encode(int n)

{

	int tmp[8];

	int cnt, sum;

	

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

	{

		tmp[i] = n%10;

		n /= 10;

	}



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

	{

		cnt = 0;

		

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

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



		n += fact[8-i-1] * cnt;

	}

	return n;

}



void bfs();



int main()

{

	int tmp[8];

	

	while (cin >> max_step && max_step != -1)

	{

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



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

			cin >> tmp[i];



		goal_status = tmp[0]*1e7 +tmp[1]*1e6 + tmp[2]*1e5 + tmp[3]*1e4 + tmp[4]*1e3 + tmp[5]*1e2 + tmp[6]*1e1 + tmp[7];

		bfs();

	}

	return 0;

}



void bfs()

{

	my_status p,next_status;

	p.a = inite_statue;

	p.path = "";

	queue<my_status> Q;

	char c;

	Q.push(p);



	while (!Q.empty())

	{

		p = Q.front();

		Q.pop();



		if (p.path.size() > max_step)

		{

			cout << "-1" << endl;

			return;

		}

		if (p.a == goal_status)

		{

			cout << p.path.size() << " " << p.path << endl;

			return;

		}



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

		{

			next_status.a = do_operate(i, p.a);

			c = 'A'+i;

			next_status.path = p.path + c;



			if (!isvisit[encode(next_status.a)])

			{

				isvisit[encode(next_status.a)] = true;

				Q.push(next_status);

			}

		}



	}

}



int do_operate(int mode, int number)

{

	int tmp = number;

	switch (mode)

	{

	case 0: //操作A,上下行交换

		tmp = number/1000%10*1e7 + number/100%10*1e6 + number/10%10*1e5 + number%10*1e4 + number/(10000000)%10*1e3 + number/1000000%10*1e2 + number/100000%10*10 + number/10000%10;

		break;

	case 1: //操作B,每行向后移动一位

		tmp = number/10000%10*1e7 + number/10000000%10*1e6 + number/1000000%10*1e5 + number/100000%10*1e4 + number%10*1e3 + number/1000%10*1e2 + number/100%10*10 +number/10%10;

		break;

	case 2: //操作C,旋转

		tmp = number/10000000%10*1e7 + number/100%10*1e6 + number/1000000%10*1e5 + number/10000%10*1e4 + number/1000%10*1e3 + number/10%10*1e2 + number/100000%10*10 + number%10;

		break;

	}

	return tmp;

}

你可能感兴趣的:(bfs)