您的位置:首页 > 其它

(多回顾)hdu 3567 Eight2 (bfs逆处理+打表+映射+康托压缩~)

2017-11-08 00:42 856 查看
映射的思想很重要!要理解bfs是要有一个初状态的,而利用映射的思想可以确定9种初状态。这样进行bfs就非常方便,末状态也要根据初状态的映射方法转化才行。

#include "queue"
#include "stdio.h"
#include "string"
#include "string.h"
using namespace std;

const int dir[4][2] = {{1, 0}, {0, -1}, {0, 1}, {-1, 0}};
const char step[] = "dlru";
const int fac[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};
char path[10][500010];
int Time[10][500010], pre[10][500010], vis[10][500010];

struct node {
int ct, loc, t;
int s[9];
};

int cantor(int a[]) {
int sum = 0;
for (int i = 0; i < 9; i++) {
int m = 0;

for (int j = i + 1; j < 9; j++) {
if (a[j] < a[i]) m++;
}
sum += m * fac[8 - i];
}
return sum + 1;
}

void BFS(int w, char s[]) {
queue<node> Q;
node cur, next;
for (int i = 0; i < 9; i++) cur.s[i] = s[i] - '0';
cur.loc = w;
cur.ct = cantor(cur.s);
pre[w][cur.ct] = -1;
Time[w][cur.ct] = 0;
vis[w][cur.ct] = 1;
Q.push(cur);
while (!Q.empty()) {
cur = Q.front();
Q.pop();

for (int i = 0; i < 4; i++) {
int x = cur.loc / 3 + dir[i][0];
int y = cur.loc % 3 + dir[i][1];
if (x > 2 || x < 0 || y > 2 || y < 0) continue;
next = cur;
next.loc = 3 * x + y;
next.s[cur.loc] = next.s[next.loc];
next.s[next.loc] = 0;
next.ct = cantor(next.s);
if (!vis[w][next.ct]) {
path[w][next.ct] = step[i];
pre[w][next.ct] = cur.ct;
vis[w][next.ct] = 1;
Time[w][next.ct] = Time[w][cur.ct] + 1;
Q.push(next);
}
}
}
}

void Print(int w, int key) {
if (pre[w][key] == -1)
return;
else {
Print(w, pre[w][key]);
printf("%c", path[w][key]);
}
}

int main(void) {
int t, kase = 0;
int a[10];
int b[10];
char s[10];
char e[10];
memset(vis, 0,
4000
sizeof(vis));
memset(Time, 0, sizeof(Time));
BFS(0, "012345678");
BFS(1, "102345678");
BFS(2, "120345678");
BFS(3, "123045678");
BFS(4, "123405678");
BFS(5, "123450678");
BFS(6, "123456078");
BFS(7, "123456708");
BFS(8, "123456780");

int key;

scanf("%d", &t);
while (t--) {
scanf("%s%s", s, e);
if (strcmp(s, e) == 0) {
printf("Case %d: 0\n\n", ++kase);
} else {
for (int i = 0, j = 0; i < 9; i++) {
if (s[i] == 'X') {
key = i;
} else {
a[s[i] - '0'] = ++j;
}
}

for (int i = 0; i < 9; i++) {
if (e[i] == 'X')
b[i] = 0;
else
b[i] = a[e[i] - '0'];
}

int status = cantor(b);

printf("Case %d: %d\n", ++kase, Time[key][status]);
Print(key, status);
printf("\n");
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: