【蓝桥杯】2016初赛 卡片换位 BFS

题目描述

你玩过华容道的游戏吗?这是个类似的,但更简单的游戏。看下面 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;
    }



}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值