题目青蛙跳杯子
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一:
1. 跳到相邻的空杯子里。
2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要1步,就可跳成下图局面:
WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。
样例输入
*WWBB
WWBB*
样例输出
2
样例输入
WWW*BBB
BBB*WWW
样例输出
10
数据规模和约定
我们约定,输入的串的长度不超过15
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
----------------------------
笨笨有话说:
我梦见自己是一棵大树,
青蛙跳跃,
我就发出新的枝条,
春风拂动那第 5 层的新枝,
哦,我已是枝繁叶茂。
参考
//典型的BFS(但是我不会)
// 根据青蛙跳杯子的条件,有 6 种方式的青蛙可以跳到空杯子
#include <iostream>
#include <queue>
#include <map>
using namespace std;
string str1; //初始状态
string str2; //目标状态
int ans = 0; //最终答案即至少步数
int dir[6] = {-1,-2,-3,1,2,3}; //方向,即青蛙可以跳到空杯子的位置
//节点
struct node {
string s; //当前状态
int num; //步数
int location; //空杯子位置
//带参构造函数
node(string S, int Num, int Location):s(S),num(Num),location(Location) {}
//无参构造函数
node() {}
};
queue<node> q; //存放节点队列
map<string,int> m; //记录状态
void bfs() {
int sLocation = str1.find('*'); //找到空杯子的位置
int slen = str1.size(); //字符串的长度
node n(str1,0,sLocation); //声明初始化开始节点
q.push(n); //将节点加入队列中
m[str1] = 1; //将当前状态加入集合
while(!q.empty()) {
node temp; //声明一个临时节点
n = q.front(); //获取队列中第一个节点
q.pop(); //出队操作
//判断当前状态
if(n.s == str2) {
ans = n.num;
return;
}
//注意:不要更改当前状态
for(int i = 0; i < 6; i++) {
//获得更新后的空杯子位置
int tLocation = n.location + dir[i];
//剪枝
if(tLocation < 0 || tLocation >= slen) {
continue;
}
//更新节点
//青蛙跳到空杯子
string temp_str = n.s;
swap(temp_str[tLocation],temp_str[n.location]);
//位置更新
temp.location = tLocation;
temp.s = temp_str;
temp.num = n.num+1;
//判断当前状态是否已访问
if(m[temp.s] != 1) {
m[temp.s] = 1;
q.push(temp);
}
}
}
}
int main(int argc, char** argv) {
cin >> str1 >> str2;
bfs();
cout << ans << endl;
return 0;
}```