93 魔板

93 魔板

作者: xxx时间限制: 1S章节: 宽度优先搜索

问题描述 :

在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有8个大小相同的格子的魔板:

1  2  3  4  
8  7  6  5  

我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。这是基本状态。

这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态):

“A”:交换上下两行;

“B”:将最右边的一列插入最左边;

“C”:魔板中央四格作顺时针旋转。

下面是对基本状态进行操作的示范:

A: 8 7 6 5
1 2 3 4

B: 4 1 2 3
5 8 7 6

C: 1 7 2 4
8 6 3 5

对于每种可能的状态,这三种基本操作都可以使用。 你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。

输入说明 :

只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间)不换行,表示目标状态。

注意,数据输入是顺时针的。即如果要输入目标状态:

8 7 6 5
1 2 3 4

则应该输入: 8 7 6 5 4 3 2 1

输出说明 :

第一行: 包括一个整数,表示最短操作序列的长度。

第二行: 操作序列,用字符串表示,除最后一行外,每行输出60个字符。如果有多个操作序列满足要求,则输出在字典序中最小的那个。

输入范例 :
2 6 8 4 5 7 3 1
输出范例 :
7
BCABCCB

#include <iostream>
#include <string>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int poWn[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };//阶乘
string pStr[50000];//存放排列字符串
bool p[50000] = { 0 };
struct STR
{
	string res,step;
}n,tmp;

int KT(string str)//康特展开式 判断数列排位
{
	int len = (int)str.length();
	int sum = 0;
	for (int i = 0; i < len; i++)
	{
		int min=0;
		for (int j = i + 1; j < len; j++)
		{
			if (str[i]>str[j]) min++;
		}
		sum += min*poWn[len - i - 1];
	}
	return sum + 1;
}

void changeA(string &str)//A操作
{
	reverse(str.begin(), str.end());
}

void changeB(string &str)//B操作
{
	int len = (int)str.length();
	reverse(str.begin(),str.begin()+3);
	reverse(str.begin(), str.begin() + 4);
	reverse(str.begin() + 5, str.end());
	reverse(str.begin() + 4, str.end());
}

void changeC(string &str)//B操作
{
	int temp = str[6];
	str[6] = str[5];
	str[5] = str[2];
	str[2] = str[1];
	str[1] = temp;
}

void bfs()
{
	string str = "12345678", panel = "";
	n.res = str; n.step = panel;
	p[KT(str)] = true;
	queue<STR> q;
	q.push(n);
	while (!q.empty())
	{
		n = q.front(); q.pop();
		tmp = n;//用来还原

		changeA(tmp.res);
		int kt = KT(tmp.res);
		if (p[kt] == false)
		{
			tmp.step += "A";
			pStr[kt] = tmp.step;
			q.push(tmp);
			p[kt] = true;
		}
		tmp = n;

		changeB(tmp.res);
		kt = KT(tmp.res);
		if (p[kt] == false)
		{
			tmp.step += "B";
			pStr[kt] = tmp.step;
			q.push(tmp);
			p[kt] = true;
		}
		tmp = n;

		changeC(tmp.res);
		kt = KT(tmp.res);
		if (p[kt] == false)
		{
			tmp.step += "C";
			pStr[kt] = tmp.step;
			q.push(tmp);
			p[kt] = true;
		}
	}
}

int main()
{
	bfs();
	/*string str ="12345678",sss; // 测试
	sss = str;
	changeA(sss);
	cout << sss << endl;  //87654321
	sss = str;
	changeB(sss);
	cout << sss << endl; //41236785
	sss = str;
	changeC(sss);
	cout << sss << endl; // 17245368
	*/
	string str,str1;
	for (int i = 0; i < 8; i++)
	{
		cin >> str1; str += str1;
		getchar();
	}
	//cout << str << endl;
	int kt = KT(str);
    string res = pStr[kt];
    cout << (int)res.length() << endl << res << endl;
	return 0;
}
posted @ 2020-05-12 20:48  RabbitJwr  阅读(177)  评论(0编辑  收藏  举报