蓝桥杯刷题——day8

题目一

题干

N 架飞机准备降落到某个只有一条跑道的机场。其中第i架飞机在 Ti时刻到达机场上空,到达时它的剩余油料还可以继续盘旋 Di个单位时间,即它最早可以于 Ti时刻开始降落,最晩可以于 Ti+Di时刻开始降落。降落过程需要 Li个单位时间。一架飞机降落完毕时,另一架飞机可以立即在同一时刻开始降落,但是不能在前一架飞机完成降落前开始降落。请你判断N架飞机是否可以全部安全降落。
输入: 包含多组数据。第一行包含一个整数T,代表测试数据的组数。对于每组数据,第一行包含一个整数N。以下N行,每行包含三个整数Ti,Di,Li。
输出: 对于每组数据,输出 YES 或者 NO,代表是否可以全部安全降落。
示例一:

输入:
2
3
0 100 10
10 10 10
0 2 20
3
0 10 20
10 10 20
20 10 20
输出:
YES
NO

题目链接: 飞机降落

解题思路

这条题目我并没有完全通过,所以我只是将我的思路说一下,如果发现问题欢迎私信或者评论。首先我们创建一个新的类Plane,这个类记录了飞机到达时间T,飞机最多可以盘旋的时间D,以及飞机降落所需的时间T,然后创建一个ArrayList,用ArrayList依次接受我们输入的Plane,然后将ArrayList进行排序,排序的准则是先处理最“紧急”的飞机,即最晚开始降落时间 T + D 较早的飞机,能尽量确保这些紧急飞机降落成功。然后创建一个变量:currentTime,这个变量表示:记录跑道的当前空闲时间,也就是当前跑道可以开始接纳下一架飞机的时间。然后依次将排序好的Plane的T和currentTime进行对比,如果跑道空闲时间(currentTime)早于飞机的到达时间(T),说明跑道已经空闲,但这架飞机还没有到达。在这种情况下,跑道必须等待飞机到达,因此需要将currentTime更新为飞机的到达时间 plane.T,如果跑道空闲时间大于等于飞机的到达时间,说明跑道空闲时间和飞机到达时间之间没有冲突。此时,跑道可以直接安排飞机降落。这时候我们要判断跑道的当前空闲时间是否超过飞机允许的最晚降落时间,如果超过则返回false,然后更新currentTime:currentTime = plane.L + currentTime ,如果遍历完整个链表后,都没有返回false,那么返回true。下面是完整代码:

代码

import java.util.ArrayList;
import java.util.Scanner;

class Plane {
    int T; // 飞机到达时间
    int D; // 飞机最多可以盘旋的时间
    int L; // 飞机降落所需的时间

    public Plane(int t, int d, int l) {
        T = t;
        D = d;
        L = l;
    }
}

public class Main {
    public static boolean Plane_isLanding(ArrayList<Plane> list) {
        int size = list.size();
        int currentTime = 0; // 跑道当前的空闲时间

        list.sort((a, b) -> (a.T + a.D) - (b.T + b.D)); // 按照飞机最晚降落开始时间排序

        for (Plane plane : list) {
            if (currentTime < plane.T) {
                currentTime = plane.T; // 如果跑道空闲时间早于飞机到达时间,更新为飞机到达时间
            }

            if (currentTime > plane.T + plane.D) {
                return false; // 如果当前时间超过飞机允许的最晚降落时间,返回 false
            }

            currentTime += plane.L; // 更新跑道空闲时间,表示当前飞机完成降落后跑道的空闲时间
        }

        return true; // 所有飞机都可以安全降落,返回 true
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt(); // 读取测试数据组数
        while (n > 0) {
            ArrayList<Plane> list = new ArrayList<>();
            int num = scanner.nextInt(); // 每组数据中的飞机数量
            while (num > 0) {
                int t = scanner.nextInt(); // 飞机到达时间
                int d = scanner.nextInt(); // 飞机盘旋的最大时间
                int l = scanner.nextInt(); // 飞机降落所需时间
                list.add(new Plane(t, d, l)); // 添加飞机信息到列表
                num--;
            }

            if (Plane_isLanding(list)) {
                System.out.println("YES"); // 如果所有飞机可以安全降落,输出 "YES"
            } else {
                System.out.println("NO"); // 如果无法满足条件,输出 "NO"
            }

            n--;
        }
        scanner.close(); // 关闭输入流
    }
}

题目二

题干

一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。
输入: 给定一个正整数N,请计算从1到N一共有多少个好数。
输出: 一个整数代表答案。
示例一:

输入:
24
输出:
7
解释:
24 以内的好数有 1,3,5,7,9,21,23,一共7个。

示例二:

输入:
2024
输出:
150

题目链接: 好数

解题思路

这条题目相对来说比较简单,用动态规划就可以轻易解决了,我们定义数组dp[i]表示在1到i一共有dp[i]个好数,那么dp[i+1]就可以表示成:
在这里插入图片描述
那么问题又变成了如何判断一个数是否是好数,题目说从低位到高位的顺序,奇数位上的数字是奇数,偶数位上的数字是偶数,那么我们可以设置一个布尔类型的flag,这个flag用于判断此位置是奇数位还是偶数位(不是判断奇偶数哟,例:个位是奇数位,十位是偶数位),同时在将该位置上的数字拿到(对10进行取余就可以了),然后判断该位置是否满足”好数“的标准就可以了,下面是完整代码:

代码

import java.util.Scanner;
public class Main {
    public static boolean is_good_number(int i) {
        boolean flag = true;
        while (i > 0) {
            int remaining = i % 10;
            if (flag && (remaining % 2 != 0)){
                flag = false;
            } else if (!flag &&(remaining % 2 == 0)){
                flag = true;
            }else {
                break;
            }
            i = i/10;
        }
        return i == 0;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = scanner.nextInt();
        int[] dp = new int[num + 1];
        dp[1] = 1;
        for (int i = 2; i <= num; i++) {
            if (is_good_number(i)){
                dp[i] = dp[i - 1] + 1;
            }else {
                dp[i] = dp[i-1];
            }
        }
        System.out.println(dp[num]);
    }
}

如果这篇博客对你有帮助,别忘了点赞+收藏哦,如果有任何的问题或者意见,欢迎评论和私信,谢谢各位!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Solitudefire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值