题目 1878: 蓝桥杯2017年第八届真题-青蛙跳杯子

题目

X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。

*WWWBBB

其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。

X星的青蛙很有些癖好,它们只做3个动作之一:

  1. 跳到相邻的空杯子里。
  2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
  3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。

对于上图的局面,只要1步,就可跳成下图局面:

WWW*BBB

本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。

输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。

输入
输入为2行,2个串,表示初始局面和目标局面。

输出
输出要求为一个整数,表示至少需要多少步的青蛙跳。

样例输入

*WWBB
WWBB*

样例输出

2

解题思路

本题是一道变化前后对应的题目,是典型的广度优先搜索的题目,类似的题目有题目 1426: 蓝桥杯历届试题-九宫重排

广度优先搜索的基本思路是:建立一个队列,将初始状态的字符串存入其中,再建立一个map,存储变换到每一个字符串需要几次变换,以及该字符串是否曾经出现过。

不断对队列中最前面的字符串进行变换,若变换后的字符串和结果一致,输出该字符串在map中对应的所需变换次数;若不一致,则判断该字符串是否出现过,若未出现过,则存入队列且在map中存储相应的变换次数。

代码

#include<bits/stdc++.h>
using namespace std;
queue <string> q;
map <string,int> maps;
string a,b;
int steps;

void BFS(){
    int i,len,sub_empty;//sub_empty空位的下标
    int sc,F = 0;//是否找到一致的
    while (!q.empty()){
        string d,c = q.front();
        q.pop();//出队
        len = c.size();
        sc = maps[c];
        for (i=0;i<c.size();i++)//找到空位
            if (c[i]=='*')
                break;
        sub_empty = i;
        
        for (i=sub_empty-3;i<=(sub_empty+3);i++)
        {       
            if (i>-1 && i!=sub_empty && i<len)//防止下标越界
            {
                d = c;
                d[sub_empty] = c[i];
                d[i] = c[sub_empty];//交换位置即表示跳跃
                if (d==b)//符合了
                {
                    F = 1;
                    steps = sc+1;
                    break;
                }
                if (maps[d]==0)//未出现过
                {
                    q.push(d);
                    maps[d] = sc+1;
                }
            }
        }
        if (F==1)
            break;
    }
}

int main()
{
    cin >> a >> b;
    q.push(a);//入队
    maps[a] = 0;
    if (a==b)
        printf("0");
    else
    {
        BFS();
        printf("%d",steps);
    }
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值