dotcpp1878-- 青蛙跳杯子(BFS)

[蓝桥杯][2017年第八届真题]青蛙跳杯子

时间限制: 1Sec 内存限制: 128MB

题目描述

X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。

如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。

*WWWBBB

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

X星的青蛙很有些癖好,它们只做3个动作之一:
1. 跳到相邻的空杯子里。
2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。

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

WWW*BBB

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

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

输入

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

输出

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

样例输入

*WWBB
WWBB*

样例输出

2

这道题和密码锁问题非常的类似  https://blog.csdn.net/qq_44786250/article/details/105623263

只不过是判断的方法和枚举的方式发生了些许的变换,但是总体思路基本一样

枚举的时候各种判断非常的重要!

据我的观察,青蛙的颜色并没有什么**用,就是忽悠人的

只不过自己吧字符串的名字顺手打错了,调了好半天才发现,差点疯掉了都!!!

#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<vector>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
inline int _read() {
    char ch = getchar();
    int sum = 0;
    while (!(ch >= '0' && ch <= '9'))ch = getchar();
    while (ch >= '0' && ch <= '9')sum = sum * 10 + ch - 48, ch = getchar();
    return sum;
}
const int inf=0x3f3f3f3f;
const int mm=0;
struct node{
	string s;
	int step;
	node(){}
	node(string st,int b):s(st),step(b){}
};
queue<node>q;
int n;
string str;
string goal;
map<string,int>mp;

string swapp(string s,int a,int b){
	string t=s;
	char tmp=t[a];
	t[a]=t[b];
	t[b]=tmp;
	return t;
}

int bfs(){
	q.push(node(str,0));
	mp[str]=1;
	while(!q.empty()){
		node now=q.front();
		q.pop();
		//cout<<"now\t"<<now.s<<endl;
		if(now.s==goal)
			return now.step;
		for(int i=0;i<n;i++){
			if(now.s[i]!='*'){
				for(int j=-3;j<=3;j++){
					int nx=j+i;
					if(nx<0||nx>=n||now.s[nx]!='*'||nx==i)
						continue;
					string tmp=swapp(now.s,i,nx);//这里 是now.s不是str!!!! 
					if(mp[tmp]!=0)
						continue;
					mp[tmp]=1;
				//	cout<<"temp\t"<<tmp<<endl;
					q.push(node(tmp,now.step+1));
				}
			}
		}
	}	
}

int main()
{
	cin>>str>>goal;
	n=str.length();
	if(str==goal)
		printf("0\n");
	else{
		int res=bfs();
		cout<<res<<endl;
	}

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值