问题描述
X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一:
1. 跳到相邻的空杯子里。
2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要1步,就可跳成下图局面:
WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。
X星球的居民喜欢把它们放在一排茶杯里,这样可以观察它们跳来跳去。
如下图,有一排杯子,左边的一个是空着的,右边的杯子,每个里边有一只青蛙。
*WWWBBB
其中,W字母表示白色青蛙,B表示黑色青蛙,*表示空杯子。
X星的青蛙很有些癖好,它们只做3个动作之一:
1. 跳到相邻的空杯子里。
2. 隔着1只其它的青蛙(随便什么颜色)跳到空杯子里。
3. 隔着2只其它的青蛙(随便什么颜色)跳到空杯子里。
对于上图的局面,只要1步,就可跳成下图局面:
WWW*BBB
本题的任务就是已知初始局面,询问至少需要几步,才能跳成另一个目标局面。
输入为2行,2个串,表示初始局面和目标局面。
输出要求为一个整数,表示至少需要多少步的青蛙跳。
样例输入
*WWBB
WWBB*
WWBB*
样例输出
2
样例输入
WWW*BBB
BBB*WWW
BBB*WWW
样例输出
10
数据规模和约定
我们约定,输入的串的长度不超过15
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
----------------------------
笨笨有话说:
我梦见自己是一棵大树,
青蛙跳跃,
我就发出新的枝条,
春风拂动那第 5 层的新枝,
哦,我已是枝繁叶茂。
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
----------------------------
笨笨有话说:
我梦见自己是一棵大树,
青蛙跳跃,
我就发出新的枝条,
春风拂动那第 5 层的新枝,
哦,我已是枝繁叶茂。
这个问题如果知道思路的话,并不是很难,但是想到这个思路就真的非常困难,所以把重点放在了如何根据这个题想到的使用BFS来做。
首先我们知道只有一个'*'在这个字符串中,那么也就是两边的青蛙可以跳到这个空位置上来的只有六个,那么在这个跳完了之后,在这种形态之下,我们紧接着往后进行,那么我们就会利用到之前的状态,如果利用了之前的状态,我们就会发现,别的方法大多都是从这一条路一直走到天黑,如果这条路错了的话,才会回头,只有BFS会记录下之前的每一个状态,从这一个状态下,添加新的状态,所以还是BFS解决这个问题会好一些。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <map>
#include <queue>
#include <cmath>
#include <math.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int MAXN = 20;
string str,ans;
int dir[6] = {-1,-2,-3,1,2,3};
struct Node //结构体表示跳每一次的状态
{
string s; //这种状态下青蛙的状态
int step; //到达这种状态下,所需要的步数
int pos; //*所在的位置
Node(string S,int Step,int Pos)
{
s =S;step = Step;pos = Pos;
}
Node()
{
}
};
queue<Node> q; //BFS队列
map<string,int> mapp; //我们为了防止产生重复,所以每一种状态都只能出现一次,map[string] ==1表示之前已经跳到过这种状态
void BFS()
{
int len = str.size();
int pos = str.find('*');
Node p = Node(str,0,pos); //构造函数生成结构体变量
q.push(p); //放到队列中
mapp[str] = 1; //将这种状态保存为已经存在,到这里上面表示的是将最开始的状态放到队列中,然后再这个最开始的基础之上进行计算
while(!q.empty())
{
Node temp;
p = q.front(); //取出开始放入的一个元素
q.pop();
if(p.s == ans) //找到答案,就将步数输出
{
cout<<p.step<<endl;
return ;
}
for(int i =0 ;i < 6;i ++) //只能朝六个方格行进,这里遍历六种情况
{
temp.pos = p.pos + dir[i]; //新的状态下*的位置
if(temp.pos < 0 || temp.pos >= len) //新位置不符合状态,直接删除掉
continue;
string str_temp = p.s;
swap(str_temp[temp.pos],str_temp[p.pos]);
temp.s = str_temp; //新状态下的新的字符串
temp.step = p.step +1; //步数要在原来基础之上加1,因为在原来基础之上跳了一步
if(!mapp[temp.s]) //当map中不存在这种状态时
{
q.push(temp); //放入队列
mapp[temp.s] = 1;
}
}
}
}
void Init()
{
cin>>str>>ans;
}
void solve()
{
BFS();
}
int main()
{
Init();
solve();
}
问题描述
如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着。与空格子相邻的格子中的卡片可以移动到空格中。经过若干次移动,可以形成第二个图所示的局面。


我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。


我们把第一个图的局面记为:12345678.
把第二个图的局面记为:123.46758
显然是按从上到下,从左到右的顺序记录数字,空格记为句点。
本题目的任务是已知九宫的初态和终态,求最少经过多少步的移动可以到达。如果无论多少步都无法到达,则输出-1。
输入格式
输入第一行包含九宫的初态,第二行包含九宫的终态。
输出格式
输出最少的步数,如果不存在方案,则输出-1。
样例输入
12345678.
123.46758
123.46758
样例输出
3
样例输入
13524678.
46758123.
46758123.
样例输出
22
问题和上面的类似,只不过如果这里使用map中字符串相互匹配的话,很容易就会超时,所以将map中的字符串匹配转换为数字的匹配,这里面1234.5678转换为数字就是:123456784 最后一位表示小数点所在的位置,这样就乐意解决了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <algorithm>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
const int MAXN = 15;
int dir[9][4] = {{1,3},{0,2,4},{1,5},{0,4,6},{1,3,5,7},{2,4,8},{3,7},{6,4,8},{5,7}};
int cnt[9] = {2,3,2,3,4,3,2,3,2};
string ans;
struct state
{
string str;
int pos;
int step;
state(string str,int pos,int step):str(str),pos(pos),step(step){}
state(){}
};
map<int,int> m;
queue<state> que;
int get_num(string a)
{
int num = 0,pos;
for(int i = 0;i < 9;i ++)
{
if(a[i] == '.')
pos = i;
else
num = num*10 + (a[i] - '0');
}
num = num*10 + pos;
return num;
}
int bfs()
{
while(!que.empty())
{
state temp = que.front();
que.pop();
if(temp.str == ans)
return temp.step;
for(int i = 0;i < cnt[temp.pos];i ++)
{
string s = temp.str;
swap(s[temp.pos],s[dir[temp.pos][i]]);
if(m[get_num(s)] == 0)
{
m[get_num(s)] ++;
que.push(state(s,dir[temp.pos][i],temp.step+1));
}
}
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
state first;
cin>>first.str>>ans;
for(int i = 0;i < 9;i ++)
if(first.str[i] == '.')
{
first.pos = i;
break;
}
first.step = 0;
m[get_num(first.str)] = 1;
que.push(first);
cout<<bfs()<<endl;
}