1151. 魔板
Constraints
Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge
Description
题目和A题相同,在这里我们把数据范围扩大:N可能超过10。
请仔细考虑各种情况。
Input
输入包括多个要求解的魔板,每个魔板用三行描述。
第一行步数N,表示最多容许的步数。
第二、第三行表示目标状态,按照魔板的形状,颜色用1到8的表示。
当 N 等于 -1 的时候,表示输入结束。
Output
对于每一个要求解的魔板,输出一行。
首先是一个整数M,表示你找到解答所需要的步数。接着若干个空格之后,从第一步开始按顺序给出M步操作(每一步是A、B或C),相邻两个操作之间没有任何空格。
注意:如果不能达到,则 M 输出 -1 即可。
Sample Input
4 5 8 7 6 4 1 2 3 3 8 7 6 5 1 2 3 4 -1
Sample Output
2 AB 1 A 评分:M超过N或者给出的操作不正确均不能得分。
Problem Source
ZSUACM Team Member
这题用的广搜,由于题目的测试样例变复杂,深搜会爆(我没试过,感觉上会爆)。但是有个问题,广搜是不好存路径的,其实这个问题很好解决,直接从起点“12345678”广搜到所有终点,用一个string数组来存储路径字符串。
这样带来一个新问题:数组下标最大要开到12345678,这是不可能的,注意到很多下标都被浪费了,比如112、11。其实8! = 40320,我们只需要40320个string的空间即可,具体方法百度康托展开。
这样就变成了一个类似于找到迷宫最短路径的问题,只不过现在迷宫的出口变成了迷宫中的每一个地点,相当于找到到达迷宫中每一个地点的最短路。
#include <algorithm>
#include <iostream>
#include <string>
#include <stdio.h>
#include <queue>
#include <string.h>
#include <vector>
#include <iomanip>
#include <map>
#include <stack>
#include <functional>
#include <list>
#include <cmath>
using namespace std;
struct step {
string way;
string num;
step() {}
step(string w, string n) {
way = w;
num = n;
}
};
string S[40325];
int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
bool exist[40325];
inline int KT(string s) {
int i, j, t, sum;
sum = 0;
for (int i = 0; i < s.size(); i++) {
t = 0;
for (int j = i + 1; j < s.size(); j++) {
if (s[j] < s[i]) t++;
}
sum += t * fac[s.size() - i - 1];
}
return sum;
}
void BFS() {
queue<step> q;
q.push(step("", "12348765"));
int pos = KT("12348765");
exist[pos] = true;
S[pos] = "";
while (!q.empty()) {
step temp = q.front();
q.pop();
string tempa, tempb, tempc;
tempa = tempb = tempc = temp.num;
// a reverse
for (int i = 0; i < 4; i++) swap(tempa[i], tempa[i + 4]);
// b reverse
char tempChar = tempb[3];
tempb[3] = tempb[2];
tempb[2] = tempb[1];
tempb[1] = tempb[0];
tempb[0] = tempChar;
tempChar = tempb[7];
tempb[7] = tempb[6];
tempb[6] = tempb[5];
tempb[5] = tempb[4];
tempb[4] = tempChar;
//c reverse
tempChar = tempc[1];
tempc[1] = tempc[5];
tempc[5] = tempc[6];
tempc[6] = tempc[2];
tempc[2] = tempChar;
int pos = KT(tempa);
if (!exist[pos]) {
exist[pos] = true;
S[pos] = temp.way + "A";
q.push(step(temp.way + "A", tempa));
}
pos = KT(tempb);
if (!exist[pos]) {
exist[pos] = true;
S[pos] = temp.way + "B";
q.push(step(temp.way + "B", tempb));
}
pos = KT(tempc);
if (!exist[pos]) {
exist[pos] = true;
S[pos] = temp.way + "C";
q.push(step(temp.way + "C", tempc));
}
}
}
int main() {
BFS();
std::ios::sync_with_stdio(false);
while (1) {
int n;
cin >> n;
if (n == -1) break;
string s;
s.resize(8);
for (int i = 0; i < 8; i++) {
cin >> s[i];
}
int pos = KT(s);
if (S[pos].size() > n) cout << -1 << endl;
else {
cout << S[pos].size() << " " << S[pos] << endl;
}
}
//getchar();
//getchar();
return 0;
}