HDU 3567 - Eight II 这该死的题

关于这道题 我真的想骂娘(好吧是自己太菜了) 我很早其实自己推出来了,就是还是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~~

猜你喜欢

转载自blog.csdn.net/Leslie5205912/article/details/82919460