【蓝桥杯】 2017初赛 青蛙跳杯子/bfs

题目描述

X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一

  1. 跳到相邻的空杯子里。
  2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
  3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
    对于上图的局面,只要1步,就可跳成该局面:WWW*BBB
    本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。

输入

输入存在多组测试数据,对于每组测试数据:
输入为2行,2个串,表示初始局面和目标局面。输入的串的长度不超过15

输出

对于每组测试数据:输出要求为一个整数,表示至少需要多少步的青蛙跳。

样例输入

WWBB
WWBB

WWWBBB
BBB
WWW

样例输出

2
10

【给自己看的】
1.这个题目有点像之前那个跳蚱蜢的(围一圈的那个),都是bfs的思路。
2.但是有几个小点,我记录一下:
(1)因为它的每个状态要记录的可能不止两个东西,所以pair无法记录的情况下,可以用结构体啊,写上构造函数,还蛮美滋滋。
(2)还有你的vis数组。写的真的有点鬼畜,push进去之后就得改vis了,同时注意第一个得直接改昂
(3)吸取上次那个蚱蜢的一个不太好的写法,就是交换的时候直接在当前状态改,这样造成一个麻烦,判断完之后又要交换回来。所以比较好的写法是在设一个字符串来改。

#include <bits/stdc++.h>
#define ll long long
using namespace std;
typedef map<string,int> mp;

struct node{
    string ss;
    int ps;
    int stp;
    node(string sss,int pss,int stpp)
    {
        ss=sss;
        ps=pss;
        stp=stpp;
    }
};//每种状态记录的结构体
int dx[10]={-1,1,-2,2,3,-3};//转移函数
string a,b;//输入进来的两字符串

int xpos;//记a的*在什么位置
int l;//记字符串的长度
int bfs()
{
    queue<node> qu;
    mp vis;
    qu.push(node(a,xpos,0));
    vis[a]=1;
    while(!qu.empty())
    {
        node tem=qu.front();
        if(tem.ss==b)
        {
                //cout<<tem.second+1<<endl;
                return tem.stp;
        }//满足条件就退出


        qu.pop();
        for(int i=0;i<6;i++)//开始探索移动方式
        {

            int mbpos=tem.ps+dx[i];
            if((mbpos)<0||(mbpos)>=l)//探索的位置超出了字符串位置
                continue;
            string temss=tem.ss;//再设一个字符串来改便位置
            char hhhx=temss[tem.ps];
            temss[tem.ps]=temss[mbpos];
            temss[mbpos]=hhhx;
            //swap(temss[tem.ps],temss[mbpos]);

            if(vis.count(temss)==0)
            {
                qu.push(node(temss,mbpos,tem.stp+1));
                vis[temss]=1;
            }


        }


    }
}
int main()
{
       while(cin>>a>>b)
       {
           l=a.length();
            for(int i=0;i<l;i++)
            {
                if(a[i]=='*')
                   {
                      xpos= i;
                      break;
                   }
            }

            cout<<bfs()<<endl;
       }

        //vis.clear();


    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值