(多回顾)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;
}
#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;
}
相关文章推荐
- HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
- HDU1044 Collect More Jewels(BFS+DFS+地图压缩)
- hdu 2209 翻纸牌游戏 (状态压缩+逆向BFS)
- HDU 3567 八数码问题2 双BFS求解
- HDU 4634 Swipe Bo 状态压缩+BFS最短路
- HDU1429胜利大逃亡(续)&&HDU 1885 Key Task BFS+状态压缩+水
- HDU 3220 Alice’s Cube 按位压缩表示状态+BFS
- [BFS + 打表] HDU 3567
- HDU 1885 Key Task (状态压缩+BFS)
- hdu 1429 胜利大逃亡(续)(bfs+状态压缩)
- hdu2612 Find a way--BFS & 打表
- hdu 1043 Eight(bfs+康托)
- hdu 1429 胜利大逃亡(续)(BFS+位压缩)
- HDU 1429 胜利大逃亡(续)(状态压缩表示,BFS)
- hdu 3681 二分+状态压缩dp+bfs
- HDU1429胜利大逃亡(续)&&HDU 1885 Key Task BFS+状态压缩+水
- hdu 3681 Prison Break (状态压缩dp/dfs + bfs)
- hdu 1885 Key Task(状态压缩+bfs)
- HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)
- 钥匙计数之一 - HDU 1438(状态压缩打表)