题目链接 https://www.jisuanke.com/course/709/36558
题解:
直接广度优先搜索,棋盘状态用9位整数表示,移位的时候可以用itoa或者atoi函数转成字符串处理。可以用map映射来避免重复搜索。
需要特别注意的是:itoa函数是非c++标准库函数,在windows平台下可以直接用,但是代码上传给OJ会编译错误。。。
也就是说itoa和atoi函数中atoi可以用,itoa不行,要用itoa函数的话,可以用sprintf()函数转,比如:
sprintf(s,"%d",num);就是将整数num转成字符串s
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
using namespace std;
struct Node {
int state,step;
};
int a;
char s[100];
map<int,int> m;
// i = 1...12
int Rotate(int i,int num) {
itoa(num,s,10);
char temp = 0;
if(i == 1) {
temp = s[0];
s[0] = s[1],s[1] = s[2],s[2] = temp;
} else if(i == 2) {
temp = s[3];
s[3] = s[4],s[4] = s[5],s[5] = temp;
} else if(i == 3) {
temp = s[6];
s[6] = s[7],s[7] = s[8],s[8] = temp;
} else if(i == 4) {
temp = s[0];
s[0] = s[2],s[2] = s[1],s[1] = temp;
} else if(i == 5) {
temp = s[3];
s[3] = s[5],s[5] = s[4],s[4] = temp;
} else if(i == 6) {
temp = s[6];
s[6] = s[8],s[8] = s[7],s[7] = temp;
} else if(i == 7) {
temp = s[0];
s[0] = s[3],s[3] = s[6],s[6] = temp;
} else if(i == 8) {
temp = s[1];
s[1] = s[4],s[4] = s[7],s[7] = temp;
} else if(i == 9) {
temp = s[2];
s[2] = s[5],s[5] = s[8],s[8] = temp;
} else if(i == 10) {
temp = s[0];
s[0] = s[6],s[6] = s[3],s[3] = temp;
} else if(i == 11) {
temp = s[1];
s[1] = s[7],s[7] = s[4],s[4] = temp;
} else if(i == 12) {
temp = s[2];
s[2] = s[8],s[8] = s[5],s[5] = temp;
}
return atoi(s);
}
bool Check(int x) {
return x == 123456789;
}
int BFS() {
queue<Node> q;
Node first = (Node){a,0};
q.push(first);
Node front;
while(!q.empty()) {
front = q.front();
q.pop();
if(Check(front.state)) {
return front.step;
}
int temp = 0;
for(int i = 1;i <= 12;i++) {
temp = Rotate(i,front.state);
if(m[temp] == 0) {
q.push((Node){temp,front.step+1});
m[temp] = 1;
}
}
}
return -1;
}
int main() {
int a1,a2,a3;
scanf("%d%d%d",&a1,&a2,&a3);
a = a1*1000000+a2*1000+a3;
printf("%d\n",BFS());
return 0;
}