关于这道题 我真的想骂娘(好吧是自己太菜了) 我很早其实自己推出来了,就是还是bfs+康托但是列举九种不同的X位置,同时利用映射,注意要映射第一个输入的模板,然后倒序输出路径!!很重要 我一开始天真的想用路径urld然后顺序输出 然后- - 也就几个小时没了吧小问题
但是我卡在了两个莫名其妙的问题上 ** 康拓展开后面return忘记+1**,导致字典序在实例
5742631X8
156834X27 时 正确答案显示路径为rulldruurdlulddrruldl 错误显示为 uurdldrulldruurdluldd
关于这个return值+1的问题我还是没能懂 尽管我知道康拓展开最后的加1是显示那个排序的次序,但是为什么不加1会导致我的字典序出现问题?这里希望大佬能帮忙解答!!
第二个问题是没有考虑两个输入相同的情况,也就是根本不用动,可想而知,输出会出现du或者lr
嗯应该就只有我会摔这么多次吧
#include<iostream>
#include <string>
#include <queue>
#include<cstring>
#include <map>
using namespace std;
struct Node {
int board[9];
int x_index;
int child;
};
struct Step {
char dir;
int parent;
};
string direction = "dlru";
int dir[4][2] = { { 1,0 } ,{ 0,-1 },{ 0,1 },{ -1,0 } };
Step step_rec[9][370000];
int finish[9][9] = {
{ 9,1,2,3,4,5,6,7,8 },
{ 1,9,2,3,4,5,6,7,8 },
{ 1,2,9,3,4,5,6,7,8 },
{ 1,2,3,9,4,5,6,7,8 },
{ 1,2,3,4,9,5,6,7,8 },
{ 1,2,3,4,5,9,6,7,8 },
{ 1,2,3,4,5,6,9,7,8 },
{ 1,2,3,4,5,6,7,9,8 },
{ 1,2,3,4,5,6,7,8,9 }
};
int fac[9];
void set_fac() {
fac[0] = 1;
for (int i = 1; i <= 8; ++i) {
fac[i] = fac[i - 1] * i;
}
}
int board_hash(int finish[]) {
int k, ans = 0;
for (int i = 0; i <= 8; ++i) {
k = 0;
for (int j = i + 1; j <= 8; ++j) {
if (finish[i] > finish[j])++k;
}
ans += fac[8 - i] * k;
}
return ans + 1;
}
void bfs(int finish[], int x_index) {
queue<Node>Q;
Node current, temp;
int tempx, tempy;
for (int i = 0; i <= 8; ++i)current.board[i] = finish[i];
current.x_index = x_index;
current.child = 0;
step_rec[x_index][current.child].parent = 0;
Q.push(current);
while (!Q.empty()) {
current = Q.front();
Q.pop();
for (int i = 0; i < 4; ++i) {
tempx = current.x_index / 3 + dir[i][0];
tempy = current.x_index % 3 + dir[i][1];
if (tempx < 0 || tempy < 0 || tempx>2 || tempy>2)continue;
temp = current;
temp.x_index = tempx * 3 + tempy;
//try to change
int t = temp.board[temp.x_index];
temp.board[temp.x_index] = temp.board[current.x_index];
temp.board[current.x_index] = t;
temp.child = board_hash(temp.board);
if (step_rec[x_index][temp.child].parent == -1) {
step_rec[x_index][temp.child].dir = direction[i];
step_rec[x_index][temp.child].parent = current.child;
Q.push(temp);
}
}
}
}
int main() {
map<int, int>change;
string original;
string final_type;
int fin_board[9];
set_fac();
memset(step_rec, -1, sizeof(step_rec));
//initialization
for (int i = 0; i <= 8; ++i) {
bfs(finish[i], i);
}
int times;
cin >> times;
getchar();
int n = times;
for (int i = 1; i <= n; ++i) {
getline(cin, original);
getline(cin, final_type);
cout << "Case " << i << ": ";
if (original == final_type) {
cout << 0 << endl << endl;
continue;
}
//Output format
//board1 is finish
//board2 is the child
//map board1
int k = -1;
for (int j = 0; j < original.size(); ++j) {
if (original[j] == 'X')k = j;
else {
if (k == -1)change[original[j] - '0'] = j + 1;
else change[original[j] - '0'] = j;
}
}
//complete the fin_board
for (int j = 0; j < final_type.size(); ++j) {
if (final_type[j] == 'X')fin_board[j] = 9;
else {
fin_board[j] = change[final_type[j] - '0'];
}
}
string way = "";
int ans = board_hash(fin_board);
while (ans&&ans != -1) {
way += step_rec[k][ans].dir;
ans = step_rec[k][ans].parent;
}
cout << way.size() << endl;
//pay attention reverse output!
for (int j = way.size() - 1; j >= 0; --j)cout << way[j];
cout << endl;
}
}
Up~~