蓝桥杯 历届试题 青蛙跳杯子 java bfs 实现 其中包括java字符串某两个元素交换位置

问题描述

  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));
	}

}

评测详情:

详细记录
评测点序号 评测结果 得分 CPU使用 内存使用 下载评测数据
1 正确 16.67 140ms 19.18MB 输入 输出
2 正确 16.67 171ms 18.99MB VIP特权
3 正确 16.67 187ms 20.23MB VIP特权
4 正确 16.67 203ms 20.02MB VIP特权
5 正确 16.67 437ms 60.76MB VIP特权
6 正确 16.67 375ms 61.08MB VIP特权

猜你喜欢

转载自blog.csdn.net/Look_star/article/details/88559453