美文网首页
2017年Java方向C组第九题

2017年Java方向C组第九题

作者: D丝学编程 | 来源:发表于2021-03-23 10:41 被阅读0次

标题:青蛙跳杯子

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 层的新枝,
哦,我已是枝繁叶茂。

解析:

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.TreeSet;

//WWW*BBBWWWBBBW
//BBB*WWWBBBWWWW
//结果:20,用于测试执行速度
class MyNode
{
    String str;  //字符串
    int step;   //字符串变化中的步骤是第几步
    public MyNode(String str,int step)
    {
        this.str = str;
        this.step = step;
    }
}
public class T09 
{
    //存储所有跳杯子过程中的字符串,用于循环中查重,剪枝
    //此处不能使用ArrayList或LinkedList,执行效率会很低下。
    static TreeSet<String> set = new TreeSet<String>(); 
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        String strStart = input.next();
        String strEnd = input.next();
        jump(strStart,strEnd);
    }   
    public static void jump(String strStart,String strEnd)
    {
        Queue<MyNode> queue = new LinkedList<MyNode>();
        queue.add(new MyNode(strStart,0));  //队列中添加第一个元素
        set.add(strStart); //set中添加第一个元素
        while(queue.size() != 0)
        { 
            MyNode myNode = queue.poll(); //队列取出第一个元素并且删除第一个元素
            //System.out.println("------"+myNode.str );
            if(myNode.str.equals(strEnd)) //如果当前队列内容和目标内容相同,则程序结束
            {
                System.out.println(myNode.step);
                break;
            }
            char[] arrCh = myNode.str.toCharArray();  //字符串转字符数组
            int index = myNode.str.indexOf("*");   //确定*的位置
            //确定交换的开始和结束位置
            int start = index-3;   //与*交换的开始位置
            int end = index + 3; //与*交换的结束位置
            if(start <= 0) start = 0;
            if(end >= arrCh.length - 1) end = arrCh.length-1;
            //循环计算当前节点下所有跳杯后的结果
            for (int i = start; i <=end; i++)
            {
                if(arrCh[i] == '*')   //自己和自己不用交换
                    continue;
                swap(arrCh,i,index); //交换跳杯
                //判断当前交换后的字符串在原始的set中是否存在,不存在则需要添加到队列,存在则不需要添加
                if(set.contains(String.valueOf(arrCh)) == false)
                {
                    MyNode tempNode = new MyNode(String.valueOf(arrCh), myNode.step+1);
                    queue.add(tempNode);
                    set.add(tempNode.str);
                    //System.out.println(tempNode.str + "," + tempNode.step);
                }
                swap(arrCh,i,index); //还原交换跳杯
            }   
        }
    }
    public static void swap(char[] arr,int i,int j)
    {
        char temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }   
}

备注:

(1)此题思路为用队列Queue存储第一个自定义节点MyNode,节点字符串为题目输入开始字符串,step为0,

(2)然后取出Queue队列的每个元素,并且删除该元素,将该元素可以移动成为的所有字符串在添加到Queue队列中,并且将其step赋值当前节点的step+1.(此处如果交换计算得出的字符串在TreeSet中已经存在则不添加,实现模拟剪枝操作)。

(3)在不停的取Queue队列每个元素过程中,判断当前节点的字符串是否和目标字符串相等,相等则打印step结果。

(4)此题中step的变化一定是从小到大的,也就是说一定是将step=1的所有字符串处理完成后才会处理step=2的情况,所以只要出现相等情况,则step就是最小值。

(5)此题存储历史字符串集合,不用使用List接口下的LinkedList或ArrayList,会超过时间,需要使用TreeSet。

相关文章

  • 2014年Java方向C组第九题

    标题:地宫取宝 X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。 ...

  • 2016年Java方向C组第九题

    四平方和 四平方和定理,又称为拉格朗日定理:每个正整数都可以表示为至多4个正整数的平方和。如果把0包括进去,就正好...

  • 2017年Java方向C组第九题

    标题:青蛙跳杯子 X星球的流行宠物是青蛙,一般有两种颜色:白色和黑色。X星球的居民喜欢把它们放在一排茶杯里,这样可...

  • 2015年Java方向C组第九题

    标题:打印大X 小明希望用星号拼凑,打印出一个大X,他要求能够控制笔画的宽度和整个字的高度。 为了便于比对空格,所...

  • 2018年Java方向C组第九题

    标题:小朋友崇拜圈 班里N个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。在一个游戏中,需要小朋友坐一...

  • 2014年Java方向C组第八题

    标题:兰顿蚂蚁 兰顿蚂蚁,是于1986年,由克里斯·兰顿提出来的,属于细胞自动机的一种。 平面上的正方形格子被填上...

  • 2015年Java方向C组第二题

    第二题 标题:立方尾不变 有些数字的立方的末尾正好是该数字本身。比如:1,4,5,6,9,24,25,.... 请...

  • 2015年Java方向C组第三题

    第三题 标题:无穷分数 无穷的分数,有时会趋向于固定的数字。 请计算【图1.jpg】所示的无穷分数,要求四舍五入,...

  • 2018年Java方向C组第四题

    标题:第几个幸运数 到x星球旅行的游客都被发给一个整数,作为游客编号。x星的国王有个怪癖,他只喜欢数字3,5和7。...

  • 2015年Java方向C组第四题

    标题:循环节长度 两个整数做除法,有时会产生循环小数,其循环部分称为:循环节。 比如,11/13=6=>0.846...

网友评论

      本文标题:2017年Java方向C组第九题

      本文链接:https://www.haomeiwen.com/subject/dltrxltx.html