题目的意思就是,可以把0的上下左右和0交换 , 从给出的状态,到达所有每一种状态。每一种状态都有一个最小到达步骤数,问哪个状态的最小到达步骤最大。输出这是的状态(这时的九宫格)还有到达这种状态做了哪些移动,
这题就是用bfs()来搜索,但没有任何结束条件,就是要一直搜到所有状态都找过去,每次搜都要记录用了多少步骤,和移动步骤的字符串。
最后输出bfs最后一层的 一个状态,和到达步骤。搜索过程中要去重,我用的是把九个数字变成一个九位数,判断是否访问过,用map映射;
AC代码:
#include<iostream>
#include<stdio.h>
#include<map>
#include<queue>
#include<string>
using namespace std;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
char dir[] = {"DURL"};
struct state {
int s[3][3];
int x,y;
string str;
int pac;
}st1,st2;
string ans;
int fina[3][3];
int res[3][3];
int mi;
int x;
int y;
queue<state> q;
map<long long ,int> m;
bool repeated (state st) {
int flag = 0;
long long fin = 0;
for (int i = 0 ;i < 3 ;i++) {
for (int j = 0 ;j < 3 ;j++) {
fin = fin * 10 + st.s[i][j];
}
}
if (m[fin] != 0)
return true;
return false;
}
void setmap (state st) {
int flag = 0;
long long fin = 0;
for (int i = 0 ;i < 3 ;i++) {
for (int j = 0 ;j < 3 ;j++) {
fin = fin * 10 + st.s[i][j];
}
}
m[fin] = 1;
}
void bfs() {
for (int i = 0 ; i < 3 ;i++) {
for (int j = 0 ; j < 3 ;j++) {
st1.s[i][j] = res[i][j];
}
}
st1.str = "";
st1.pac = 0;
st1.x = x;
st1.y = y;
mi = 0;
setmap(st1);
q.push(st1);
while (!q.empty()) {
st1 = q.front();
q.pop();
for (int i = 0 ; i < 4 ;i++) {
st2 = st1;
int xx = st2.x;
int yy = st2.y;
int nx = xx + dx[i];
int ny = yy + dy[i];
// cout << xx <<" "<< yy<<endl;;
// cout << nx <<" "<< ny <<endl;
if (nx >= 0 && nx < 3 && ny >= 0 && ny < 3) {
st2.s[xx][yy] = st2.s[nx][ny];
st2.s[nx][ny] = 0;
if(repeated(st2)) {
continue;
}
st2.pac += 1;
st2.str += dir[i];
st2.x = nx;
st2.y = ny;
q.push(st2);
setmap(st2);
if (st2.pac > mi) {
mi = st2.pac;
ans = st2.str;
for (int i = 0 ;i < 3;i++) {
for (int j = 0 ; j < 3 ;j++) {
fina[i][j] = st2.s[i][j];
}
}
}
}
}
}
return ;
}
int main () {
int t;
cin >> t;
int Case = 1;
while(t--) {
m.clear();
while(!q.empty())
q.pop();
for (int i = 0 ; i < 3;i++) {
for (int j = 0 ; j < 3 ;j++) {
scanf("%d",&res[i][j]);
if (res[i][j] == 0) {
x = i;
y = j;
}
}
}
// for (int i = 0 ; i < 3;i++) {
// for (int j = 0 ; j< 3; j++) {
// if (j != 0)
// cout << " ";
// cout << res[i][j];
// }
// cout << endl;
// }
// cout << endl;
bfs() ;
cout << "Puzzle #" << Case++ <<endl;
for (int i = 0 ;i < 3 ;i++) {
for (int j = 0 ; j < 3 ;j++) {
if (j != 0)
printf(" ");
printf("%d",fina[i][j]);
}
printf("\n");
}
cout << ans << endl<<endl;
}
return 0 ;
}