题目描述
你玩过华容道的游戏吗?这是个类似的,但更简单的游戏。看下面 3 x 2 的格子
在其中放5张牌,其中A代表关羽,B代表张飞,* 代表士兵。还有一个格子是空着的。
你可以把一张牌移动到相邻的空格中去(对角不算相邻)。
游戏的目标是:关羽和张飞交换位置,其它的牌随便在哪里都可以。
输入
输入存在多组测试数据,对于每组测试数据:
输入两行6个字符表示当前的局面
输出
一个整数,表示最少多少步,才能把AB换位(其它牌位置随意)
样例输入
样例输出
17
12
【想说的】看到这个题目,还有求最短路径什么的,很容易想到用bfs。但是怎么bfs呢。
1.虽然题目是说A,B交换位置,但是可以看作是空格的移动,根据空格的位置移动来实现BFS。
2.关于vis的取法:为了避免出现重复的形况而无限循环无结果的情况,就要使用vis数组。很容易想到:要确认一个局面,只要A,B,空格,的位置是确定的即可。那么设一个vis【A的横坐标】【A的纵坐标】【B的横坐标】【B的纵坐标】【空格的横坐标】【空格的纵坐标】
3.关于这个数组的读取,参考了一下别人的读取方式,可以getchar(但是注意要把一个空格吸收掉),我使用了两个gets读取。
4.然后就是一个BFS的写法。
整体不难就是一些细节处理,以及思考方向要正确
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
char s[5][5];
int dx[5]={0,0,1,-1};
int dy[5]={-1,1,0,0};
int xa,ya,xb,yb,xk,yk;
int vis[8][8][8][8][8][8];
typedef struct Info{
int level;
int ax;
int ay;
int bx;
int by;
int kx;
int ky;
}info;
info fir;
int bfs()
{
queue<info> qu;
while(!qu.empty())
qu.pop();
qu.push(fir);
while(!qu.empty())
{
info tem=qu.front();
vis[tem.ax][tem.ay][tem.bx][tem.by][tem.kx][tem.ky]=1;
qu.pop();
int x=tem.kx;
int y=tem.ky;
for(int i=0;i<4;i++)
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=0&&xx<2&&yy>=0&&yy<3)
{
info now;
now.kx=xx;
now.ky=yy;
now.level=tem.level+1;
if(tem.ax==xx&&tem.ay==yy)
{
now.ax=tem.kx;
now.ay=tem.ky;
}
else
{
now.ax=tem.ax;
now.ay=tem.ay;
}
if(tem.bx==xx&&tem.by==yy)
{
now.bx=tem.kx;
now.by=tem.ky;
}
else
{
now.bx=tem.bx;
now.by=tem.by;
}
if(now.ax==fir.bx&&now.ay==fir.by&&now.bx==fir.ax&&now.by==fir.ay)
return now.level;
if(vis[now.ax][now.ay][now.bx][now.by][now.kx][now.ky]==0)
qu.push(now);
}
}
}
return -1;
}
int main()
{
while(gets(s[0])!=NULL){
gets(s[1]);
memset(vis,0,sizeof(vis));
for(int i=0;i<2;i++)
{
for(int j=0;j<3;j++)
{
if(s[i][j]=='A')
{
fir.ax=i;
fir.ay=j;
}
if(s[i][j]=='B')
{
fir.bx=i;
fir.by=j;
}
if(s[i][j]==' ')
{
fir.kx=i;
fir.ky=j;
}
}
}
int cnt=bfs();
cout<<cnt<<endl;
}
}