题目描述
X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一
- 跳到相邻的空杯子里。
- 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
- 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要1步,就可跳成该局面:WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入
输入存在多组测试数据,对于每组测试数据:
输入为2行,2个串,表示初始局面和目标局面。输入的串的长度不超过15
输出
对于每组测试数据:输出要求为一个整数,表示至少需要多少步的青蛙跳。
样例输入
WWBB
WWBB
WWWBBB
BBBWWW
样例输出
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;
}