【蓝桥杯】历届试题 青蛙跳杯子(广度优先搜索bfs)(C++)

【蓝桥杯】历届试题 青蛙跳杯子

问题描述

题目链接:青蛙跳杯子 资源限制
时间限制:1.0s 内存限制:256.0MB 问题描述   X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
  X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
  如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。   
*WWWBBB
  其中,W字母表示白色青蛙,B表示黑色青蛙,表示空杯子。   X星的青蛙很有些癖好,它们只做3个动作之一:
  1. 跳到相邻的空杯子里。
  2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
  3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。   对于上图的局面,只要1步,就可跳成下图局面:   
WWW
BBB   
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。   
输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。

样例输入
WWBB
WWBB

样例输出
2

样例输入
WWWBBB
BBB
WWW

样例输出
10

思路分析

思路代码参考:【蓝桥杯】历届试题 青蛙跳杯子(广度优先搜索bfs)
看到这道题的第一想法是想让青蛙去跳来实现,但这一思路无从下手。然后参考了上面这个,转换了思路:
我们不要以青蛙为主体去对字符串的空位进行位置交换,而是转而以空位(“*”)为主体,将题目转化为“有两个字符串“例如 *WWBB和WWBB,*每次能往左或右跳1-3步,与原位置的字符交换,问跳到第二个字符串的状态的最少步数”。

代码实现

#include <iostream>
#include <queue>
#include <cstring>
#include <set>
using namespace std;

int dir[]={-3,-2,-1,1,2,3};	 //可移动的6种方案 
struct situation{			 //定义结构体:形势 
	string str;				 //当前形势下的字符串 
	int step;				 //得到当前形势的步数 
	situation(string s,int n)//构造函数 
	{
		str=s,step=n;
	}
}; 

queue <situation> q; 
set <string> s;//每一步得到的所有字符串 

void bfs(string start,string target)
{
	if(start==target)
	{
		cout<<0<<endl;
		return;
	}
	q.push(situation(start,0));
	s.insert(start);
	while(!q.empty())
	{
		situation now=q.front();//每次将要进行处理的形势放入now中 
		q.pop();
		string str=now.str;//str表示当前进行处理的字符串 
		for(int i=0;i<str.length();i++)
		{
			if(str[i]!='*')continue;//仅对空杯子的位置进行换位 
			for(int j=0;j<6;j++)//对所有方案进行遍历 
			{
				int n=i+dir[j];
				if(n>=0&&n<str.length())//如果当前换位合法 
				{
					swap(str[i],str[n]);//交换青蛙和当前空杯子的位置 
					if(str==target)//如果当前字符串等于目标字符串,则输出步数 
					{
						cout<<now.step+1<<endl;
						return;
					}
					if(!s.count(str))//如果当前字符串还未出现过 
					{
						s.insert(str);//将之前未出现过的字符串放入s集合中 
						q.push(situation(str,now.step+1));
					}
					swap(str[i],str[n]);//恢复现场 
				}
			}
		}
	}
}

int main()
{
	string str1,str2;
	cin>>str1>>str2;
	bfs(str1,str2);
	return 0;
} 

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值