HDU 3567 - Eight II 這該死的題
阿新 • • 發佈:2018-11-25
關於這道題 我真的想罵娘(好吧是自己太菜了) 我很早其實自己推出來了,就是還是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~~