资源限制
时间限制: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
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
----------------------------
笨笨有话说:
我梦见自己是一棵大树,
青蛙跳跃,
我就发出新的枝条,
春风拂动那第 5 层的新枝,
哦,我已是枝繁叶茂。
——————————————————————————————————————————————————————
思路:求最短距离或是最少操作,用BFS,还不如理解成杯子跳青蛙呢!
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
public class Main {
static String start;
static String end;
static Queue<State> q = new LinkedList<>();
static Set<String> set = new HashSet<>();//过滤纸重复的队列模式
static int[] dir = {1, 2, 3, -1, -2, -3};//六种状态,-3表示向左边跳三个距离
public static String swap(int a, int b, String str) {//交换str中 a、b 两处的字符
char cs[] = str.toCharArray();
char temp = cs[a];
cs[a] = cs[b];
cs[b] = temp;
str = new String(cs);
return str;
}
public static int bfs(String now, int pos, int step) {
q.add(new State(now, pos, step));
while(!q.isEmpty()) {
State curState = q.poll();
if(curState.pattern.equals(end)) return curState.step;
if(set.contains(curState.pattern)) {
continue;
}else {
set.add(curState.pattern);
}
for(int i = 0;i < dir.length;i++) {//六个状态
int nextPos = curState.pos + dir[i];//下一个空杯的位置
if(nextPos < curState.pattern.length() && nextPos >= 0) {//得在合法的位置
String temp = curState.pattern;//记录当前的队列状态
String nextPattern = swap(curState.pos, nextPos, temp);//交换,产生新的队列模式
State nextState = new State(nextPattern, nextPos, curState.step + 1);
if(!set.contains(nextPattern)) q.add(nextState);
}
}
}
return -1;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
start = sc.nextLine();
end = sc.nextLine();
sc.close();
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));
}
}
class State{
String pattern;//当前队列模式
int pos;// * 所在的索引
int step;//从初始队列模式到当前队列模式经过的步数
public State(String now, int pos, int step) {
this.pattern = now;
this.pos = pos;
this.step = step;
}
}