问题 D: 【宽搜入门】魔板
时间限制: 1 Sec 内存限制: 128 MB
提交: 60 解决: 17
[提交][状态][讨论版][命题人:外部导入]
题目描述
在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有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 之间),表示目标状态。
【输出格式】
Line 1: 包括一个整数,表示最短操作序列的长度。
Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。
Sample Input
2 6 8 4 5 7 3 1
Sample Output
7
BCABCCB
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int termination;
//注意要进入下一层后转化回来也得写
struct node {
int num, step;
vector<char> answer;
node(int n, int s, vector<char> a) {
num = n, step = s, answer = a;
}
};
void oper(char str[],int flag,bool operate) {
if (flag == 0) {
for (int i = 0; i < 4; i++) {
swap(str[i], str[7 - i]);
}
}
else if (flag == 1) {
if (operate == true) {
char t1 = str[3], t2 = str[4];
for (int i = 2; i >= 0; i--) {
str[i + 1] = str[i];
}
for (int i = 5; i < 8; i++) {
str[i - 1] = str[i];
}
str[0] = t1, str[7] = t2;
}
else {
char t1 = str[0], t2 = str[7];
for (int i = 0; i < 3; i++) {
str[i] = str[i + 1];
}
for (int i = 7; i >= 5; i--) {
str[i] = str[i - 1];
}
str[3] = t1, str[4] = t2;
}
}
else {
if (operate == true) {
char t = str[1];
str[1] = str[6], str[6] = str[5], str[5] = str[2], str[2] = t;
}
else
{
char t = str[1];
str[1] = str[2], str[2] = str[5], str[5] = str[6], str[6] = t;
}
}
}
queue<node> q;
map<int, bool> mp;
void BFS() {
char temp[10];
int temp1, num = 12345678;
vector<char> answer;
node s(num, 0, answer);
q.push(s);
mp[num] = true;
while (!q.empty()) {
s = q.front();
q.pop();
if (s.num == termination) {
cout << s.step << endl;
for (int i = 0; i < s.step; i++) {
cout << s.answer[i];
if (i % 60 == 0 && i) cout << endl;
}
return;
}
sprintf(temp, "%d", s.num);
for (int i = 0; i < 3; i++) {
oper(temp, i, true);
sscanf(temp, "%d", &temp1);
if (mp.count(temp1) == 0){
node r(temp1, s.step + 1, s.answer);
r.answer.push_back(i + 'A');
q.push(r);
mp[temp1] = true;
}
oper(temp, i, false);
}
}
}
int main() {
int n;
while (cin >> n) {
termination = n;
for (int i = 0; i < 7; i++) {
cin >> n;
termination = termination * 10 + n;
}
BFS();
}
return 0;
}