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;
}