这题的bfs还是很有难度的,不像平时的走迷宫问题的bfs一样,在层序遍历的时候,每个点能走的方向都是固定的,只需要用visit数组判重一下就行了,然后在入队列的时候add的是自己当前的坐标(x,y)和步数step。
这题在每个点能走的地方都是不同的,需要把整个地图都保存下来,所幸可以通过地图来判断下一步可以走的方向。可是属实不知道怎么保存地图,总不能用数组把,要是用数组那判重的visit岂不是一个很大的二维数组了。
看了别人的C++代码写的非常好,用123456789来表示最初的地图,这样visit数组就是一个int数组了,然后在判断该往哪走的时候也没有我想的那么复杂非要一下子就弄出来,只要把这个数字放到一个数组里,然后对这个数组进行4次变换就可以得到新的4个地图了。
别人的代码如下:
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <math.h>
#include <cstdio>
#include <iomanip>
#include <time.h>
#define LL long long
#define INF 0x3f3f3f3f
#define ls nod<<1
#define rs (nod<<1)+1
const int maxn = 1e9 + 10 ;
const LL mod = 20010905;
int st = 123456789,ed = 876543219;
int dir[4] = {1,-1,-2,2};
bool vis[maxn];
int a[10];
int getnum() {
int sum = 0;
for (int i = 0;i < 9;i++) {
sum *= 10;
sum += a[i];
}
return sum;
}
void bfs() {
std::queue<std::pair<int,int> > q;
memset(vis,0, sizeof(vis));
q.push(std::make_pair(st,0));
while (!q.empty()) {
int x = q.front().first;
int step = q.front().second;
q.pop();
if (vis[x])
continue;
vis[x] = true;
if (x == ed) {
printf("%d\n",step);
return ;
}
int j = 8,now;
while (x) {
if (x % 10 == 9)
now = j;
a[j--] = x % 10;
x /= 10;
}
for (int i = 0;i < 4;i++) {
std::swap(a[now],a[(now+dir[i]+9)%9]);
int val = getnum();
if (!vis[val]) {
q.push(std::make_pair(val,step+1));
}
std::swap(a[now],a[(now+dir[i]+9)%9]);
}
}
}
int main() {
bfs();
return 0;
}