题目大意:求所给图达到最远状态的时候,移动最少次的移动顺序。
解题思路:bfs+判重。定义一个结构体存放当前图,空白位置的坐标,移动次数即移动到该图的步骤。每改变一次就判断,然后放入队列。
依旧是参考别人题解的咸鱼。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
struct p {
int ch[3][3];
int x, y, step;
string str;
};
p l, n;
bool vis[999999999];
queue<p> q;
int dx[]={-1, 1, 0, 0};
int dy[]={0, 0, -1, 1};
char dic[]={"UDLR"};
int ans, res[3][3];
string s;
int has(p tmp) {
int sum = 0;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
sum = sum * 10 + tmp.ch[i][j];
if (vis[sum]) return 0;
vis[sum] = 1;
return 1;
}
void bfs() {
q.push(l);
while (!q.empty()) {
l = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int X = l.x + dx[i];
int Y = l.y + dy[i];
if (X < 0 || X > 2 || Y < 0 || Y > 2) continue;
n = l;
n.ch[l.x][l.y] = n.ch[X][Y];
n.ch[X][Y] = 0;
n.x = X;
n.y = Y;
n.str += dic[i];
if (has(n)) {
n.step += 1;
if (n.step > ans) {
ans = n.step;
memcpy(res, n.ch, sizeof(res));
s = n.str;
}
q.push(n);
}
}
}
}
int main() {
int T;
scanf("%d", &T);
for (int t = 0; t < T; t++) {
memset(vis, 0, sizeof(vis));
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++) {
scanf("%d", &l.ch[i][j]);
if (l.ch[i][j] == 0) {
l.x = i;
l.y = j;
}
}
l.step = 0;
l.str = "";
has(l);
ans = 0;
bfs();
printf("Puzzle #%d\n", t+1);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++)
printf("%d ", res[i][j]);
printf("%d\n", res[i][2]);
}
cout << s << endl << endl;
}
return 0;
}