华硕编程竞赛11月JAVA专场 C题太空遨游 题解

简介: 华硕编程竞赛11月JAVA专场 C题太空遨游 题解

题目链接:题目链接

题面:

小王最近得到了一艘神奇的飞船,这艘飞船只有两个脚踏板,分别是油门和刹车,飞船的原始速度 N

假设飞船的现有速度为 X,每当小王踩一下油门后,就会加速到 X * X

假设飞船的现有速度为 Y,每当小王踩一下刹车后,飞船速度就会减速到 Y - 1

这并不神奇,神奇的是飞船会出一道题,如果飞船驾驶员能正确解答这道题,就可以召唤出一条神龙,实现驾驶者的一个愿望。飞船出题的内容是求出踩脚踏板后达到预定的速度 M(0 < M < 400000)的最少次数

小王特别想有一个女朋友陪他一起遨游太空,你能帮助小王解决这个问题让他召唤出神龙满足有女朋友的愿望吗?

本次挑战需要你至少了解一些 Java 中诸如流程控制、数组、集合或队列的使用。

知识点

  • 队列/背包的基本使用
  • 广度优先搜索
  • 最佳解决方案

初始代码

import java.util.*;
public class SpaceShip{
    public static int fly(int N,int M){
       int ans = 0;
         //代码编辑区 开始   
         //代码编辑区 结束 
         return ans;
    }
    public static void main(String[] args) {
        //测试用例
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为3次.\n",2,15,fly(2, 15));
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为5次.\n",5,21,fly(5, 21));
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为13次.\n",5,30,fly(5, 30));
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为26次.\n",5,125,fly(5, 125));
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为78次.\n",5,173010,fly(5, 173010));
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为752次.\n",11,200000,fly(11, 200000));
        System.out.printf("从%d 到 %d 最少需要踩:%d 次,正确答案为2次.\n",52,50,fly(52, 50));
    }
}

样例说明

输入初始速度 N 和目标速度 M,输出踩脚踏板的最小次数。

如初始速度 N = 2,目标速度为 15,只需依次踩油门、油门、刹车即可达到,最少只需要踩 3 次。

如初始速度 N = 52,目标速度为 50,只需依次踩刹车、刹车即可达到,最少只需要踩 2 次。

刹车与油门可以只踩一种或交替进行踩踏。

题解

考察 Java 队列和 bfs 的使用,当然也可以用动态规划的思想去解决问题,对于初始速度 N 和目标速度 M,需要考虑到下列三种情况。

1 初始速度 N >= 目标速度 M,答案为 N - M,因为小王只能通过踩刹车减速。

2 初始速度 N < 目标速度 M,小王可以通过踩油门或刹车控制速度,使用广搜思想分类讨论,最终得出答案。

参考代码如下:

import java.util.*;
public class SpaceShipAns{
    // 请勿修改 fly() 的方法名和参数类型
    public static int fly(int n,int m){
        int ans = 0;
        //代码编辑区 开始
        if(n >= m) {
            return n - m;
        }
        init();
        integerList.set(n,0);
        q.add(new NodeVo(0,n));
        while(q.size() > 0) {
            NodeVo vo = q.peek();
            q.poll();
            if(integerList.get(vo.getId()) < vo.getT()) {
                continue;
            }
            if(vo.getId() <= 632) {
                int index = vo.getId() * vo.getId();
                int t = vo.getT() + 1;
                if(integerList.get(index) > t) {
                    integerList.set(index,t);
                    q.add(new NodeVo(t,index));
                }
            }
            if(vo.getId() > 2) {
                int index = vo.getId() - 1;
                int t = vo.getT() + 1;
                if(integerList.get(index) > t) {
                    integerList.set(index,t);
                    q.add(new NodeVo(t,index));
                }
            }
        }
        ans = integerList.get(m);
        //代码编辑区 结束
        return ans;
    }
    public static void main(String[] args) {
        //测试用例
        System.out.printf((Objects.equals(3,fly(2, 15)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 3 次\n",2,15,fly(2, 15));
        System.out.printf((Objects.equals(5,fly(5, 21)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 2 次\n",5,21,fly(5, 21));
        System.out.printf((Objects.equals(13,fly(5, 30)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 13 次\n",5,30,fly(5, 30));
        System.out.printf((Objects.equals(26,fly(5, 125)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 26 次\n",5,125,fly(5, 125));
        System.out.printf((Objects.equals(78,fly(5, 173010)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 78 次\n",5,173010,fly(5, 173010));
        System.out.printf((Objects.equals(752,fly(11, 200000)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 752 次\n",11,200000,fly(11, 200000));
        System.out.printf((Objects.equals(2,fly(52, 50)) ? "【√正确】" : "【X错误】") + "从%d 到 %d 最少需要踩:%d 次,正确答案为 2 次\n",52,50,fly(52, 50));
    }
    private static List<Integer> integerList;
    private static Queue<NodeVo> q;
    private static class NodeVo implements Comparable<NodeVo>{
        private int t;
        private int id;
        public NodeVo(int t,int id) {
            this.t = t;
            this.id = id;
        }
        public int getT() {
            return t;
        }
        public void setT(int t) {
            this.t = t;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        @Override
        public int compareTo(NodeVo other) {
            return t > other.t ? 1 : 0;
        }
    }
    private static void init() {
        integerList = new ArrayList<>();
        for(int i = 0;i < 500000; i ++) {
            integerList.add(999999999);
        }
        q = new LinkedList<>();
    }
}

总结

要 AC 本题,必须学会基于队列的 BFS (即广度优先搜索)的算法,从而通过本题。


相关文章
|
5天前
|
安全 Java 调度
Java编程时多线程操作单核服务器可以不加锁吗?
Java编程时多线程操作单核服务器可以不加锁吗?
18 2
|
8天前
|
设计模式 缓存 Java
死磕-高效的Java编程(一)
死磕-高效的Java编程(一)
|
6天前
|
前端开发 JavaScript Java
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
基于Java+Springboot+Vue开发的大学竞赛报名管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的大学竞赛报名管理系统项目,大学生可以在实践中学习和提升自己的能力,为以后的职业发展打下坚实基础。
20 3
基于Java+Springboot+Vue开发的大学竞赛报名管理系统
|
8天前
|
算法 安全 Java
JAVA并发编程系列(12)ThreadLocal就是这么简单|建议收藏
很多人都以为TreadLocal很难很深奥,尤其被问到ThreadLocal数据结构、以及如何发生的内存泄漏问题,候选人容易谈虎色变。 日常大家用这个的很少,甚至很多近10年资深研发人员,都没有用过ThreadLocal。本文由浅入深、并且才有通俗易懂方式全面分析ThreadLocal的应用场景、数据结构、内存泄漏问题。降低大家学习啃骨头的心理压力,希望可以帮助大家彻底掌握并应用这个核心技术到工作当中。
|
8天前
|
Java 程序员 编译器
死磕-高效的Java编程(二)
死磕-高效的Java编程(二)
|
3天前
|
Java
JAVA并发编程系列(13)Future、FutureTask异步小王子
本文详细解析了Future及其相关类FutureTask的工作原理与应用场景。首先介绍了Future的基本概念和接口方法,强调其异步计算特性。接着通过FutureTask实现了一个模拟外卖订单处理的示例,展示了如何并发查询外卖信息并汇总结果。最后深入分析了FutureTask的源码,包括其内部状态转换机制及关键方法的实现原理。通过本文,读者可以全面理解Future在并发编程中的作用及其实现细节。
|
6天前
|
Java 数据处理 调度
Java中的多线程编程:从基础到实践
本文深入探讨了Java中多线程编程的基本概念、实现方式及其在实际项目中的应用。首先,我们将了解什么是线程以及为何需要多线程编程。接着,文章将详细介绍如何在Java中创建和管理线程,包括继承Thread类、实现Runnable接口以及使用Executor框架等方法。此外,我们还将讨论线程同步和通信的问题,如互斥锁、信号量、条件变量等。最后,通过具体的示例展示了如何在实际项目中有效地利用多线程提高程序的性能和响应能力。
|
7天前
|
安全 算法 Java
Java中的多线程编程:从基础到高级应用
本文深入探讨了Java中的多线程编程,从最基础的概念入手,逐步引导读者了解并掌握多线程开发的核心技术。无论是初学者还是有一定经验的开发者,都能从中获益。通过实例和代码示例,本文详细讲解了线程的创建与管理、同步与锁机制、线程间通信以及高级并发工具等主题。此外,还讨论了多线程编程中常见的问题及其解决方案,帮助读者编写出高效、安全的多线程应用程序。
|
9天前
|
存储 缓存 Java
java线程内存模型底层实现原理
java线程内存模型底层实现原理
java线程内存模型底层实现原理
|
13天前
|
缓存 Java 应用服务中间件
Java虚拟线程探究与性能解析
本文主要介绍了阿里云在Java-虚拟-线程任务中的新进展和技术细节。
下一篇
无影云桌面