问题描述
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
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
----------------------------
笨笨有话说:
我梦见自己是一棵大树,
青蛙跳跃,
我就发出新的枝条,
春风拂动那第 5 层的新枝,
哦,我已是枝繁叶茂。
解析:
首先:由题, 3种操作,6个移动位置,然后看提示5层,显然是个图,那么就可以把两种状态的操作次数看成距离,把每一种操作看成两种移动,每次转换状态都需要遍历这六种移动。即距离为1的情况,距离为2的情况……bfs
其次:看状态,依题意,操作时,青蛙不分色,那就说明对于某一种状态的某一个杯子只有两种可能有青蛙,没青蛙。因而状态数2^15 再乘以6种可能移动情况,queue要保留的字符串数量最多为2^15*6 时间复杂度满足,空间亦可以存储。
再者:剪枝,防止跳入重复状态,于是乎,map存储其之状态。
代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
public class Main {
//青蛙跳杯子
//bfs
static class frog
{
String now;//存储字符串的状态
int pos;
long step;//pos :*号的位置,step:步数
public frog(String now,int pos,long step)
{
this.now=now;
this.pos=pos;
this.step=step;
}
}
static Queue<frog> q=new LinkedList();
static HashMap<String,Integer> mp=new HashMap<String, Integer>();
static String start,end;
static String swap(int a,int b, String c)//交换string中某两个字符的位置
{
char C[]=c.toCharArray();
char temp1=C[a];
C[a]=C[b];
C[b]=temp1;
c=new String(C);
return c;//不知道为什么,如果swap是返回void类型的,那么c就不会被改变。。。
}
static long bfs(String now,int pos,long step)
{
frog f=new frog(now,pos,step);
q.add(f);
while(!q.isEmpty())
{
frog status=q.poll();
//System.out.println(status.now+" "+status.pos+" "+status.step);
if(status.now.equals(end))
return status.step;
String temp;
if(mp.containsKey(status.now))//剪枝
continue;
else
mp.put(status.now, 1);
//六种选择 说实在的青蛙 的W与B根本就没有影响,都是青蛙,这里是以空位为移动视角的
if(status.pos+1<status.now.length())
{
temp=status.now;
temp=swap(status.pos+1,status.pos,temp);
frog nextStatus=new frog(temp,status.pos+1,status.step+1);
if(!mp.containsKey(temp))//剪枝
q.add(nextStatus);
}
if(status.pos+2<status.now.length())
{
temp=status.now;
temp=swap(status.pos+2,status.pos,temp);
frog nextStatus=new frog(temp,status.pos+2,status.step+1);
if(!mp.containsKey(temp))//剪枝
q.add(nextStatus);
}
if(status.pos+3<status.now.length())
{
temp=status.now;
temp=swap(status.pos+3,status.pos,temp);
frog nextStatus=new frog(temp,status.pos+3,status.step+1);
if(!mp.containsKey(temp))//剪枝
q.add(nextStatus);
}
if(status.pos-1>=0)
{
temp=status.now;
temp=swap(status.pos-1,status.pos,temp);
frog nextStatus=new frog(temp,status.pos-1,status.step+1);
if(!mp.containsKey(temp))//剪枝
q.add(nextStatus);
}
if(status.pos-2>=0)
{
temp=status.now;
temp=swap(status.pos-2,status.pos,temp);
frog nextStatus=new frog(temp,status.pos-2,status.step+1);
if(!mp.containsKey(temp))//剪枝
q.add(nextStatus);
}
if(status.pos-3>=0)
{
temp=status.now;
temp=swap(status.pos-3,status.pos,temp);
frog nextStatus=new frog(temp,status.pos-3,status.step+1);
if(!mp.containsKey(temp))//剪枝
q.add(nextStatus);
}
}
return -1;
}
public static void main(String[] args) throws IOException {
BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
start=bfr.readLine();
end=bfr.readLine();
int pos=0;
for(int i=0;i<start.length();i++)
{
if(start.charAt(i)=='*')
{
pos=i;
break;
}
}
System.out.println(bfs(start,pos,0));
}
}
评测详情:
详细记录 |
|