【题目链接】
http://www.dotcpp.com/oj/problem1426.html
题目意思
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。
解题思路
用BFS非常容易求出最小步数,但是怎么标记图呢?看了一些用二维标记的,感觉麻烦。所以把图变成字符串,用map处理。需要注意的是每排的最前面一个没办法到前一排最后一个。同理最后一个一样。
代码部分
/*************
*题意:略
*链接:http://www.dotcpp.com/oj/problem1426.html
*思路:把二维图转换成字符串处理,用map标记
*************/
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
#define ll long long
map<string,int>M; //标记
int dir[4]={-1,1,-3,3};//方位
struct node
{
char str[15];
ll step;
int point;
}start,ed;
bool ok(node tt)
{
if (M[tt.str]++ == 0)
return true;
else return false;
}
ll Bfs()
{
queue<node>q;
q.push(start);
while (!q.empty ())
{
node t = q.front();
q.pop();
if (strcmp(t.str,ed.str) == 0)
return t.step;
for (int i = 0; i < 4; i++)
{
//每排最后和最前不能加减1
if (i == 0 && t.point%3 == 0) continue;
if (i == 1 && t.point%3 == 2) continue;
node tt = t;
tt.step++;
tt.point += dir[i];
if (tt.point >= 0 && tt.point < 9)
{
//先交换再判断是否出现过。
swap(tt.str[tt.point],tt.str[t.point]);
if (ok(tt))
{
q.push(tt);
}
}
}
}
return -1;
}
int main()
{
scanf("%s %s",start.str,ed.str);
for (int i = 0; i < 9; i++)
if (start.str[i] == '.')
start.point = i;
start.step = 0;
M[start.str]++;
cout<<Bfs()<<endl;
return 0;
}