华为OD刷题C卷 - 每日刷题 28(转盘寿司、开源项目热度榜单)

73 篇文章 0 订阅
37 篇文章 1 订阅

1、(转盘寿司):

这段代码是解决“转盘寿司”的问题。它提供了一个Java类Main,其中包含main方法和getDiscount方法,用于计算客户选择每盘寿司时实际得到的总价格。

main方法首先读取输入的寿司价格数组,然后调用getDiscount方法并打印出享受优惠后的价格。

getDiscount方法遍历价格数组,对于每个价格,尝试找到其后面第一个价格更低的寿司盘,如果找到,则将该低价寿司的价格加到当前寿司的价格上。如果没有找到,则不进行任何操作。接着,对于每个价格,也从数组开头向前遍历,寻找更低的价格并累加,直到找到或遍历到当前价格之前。

最后,返回包含优惠后价格的新数组。

2、(开源项目热度榜单):

这段代码是解决“开源项目热度榜单”的问题。它提供了一个Java类Main,其中包含main方法和一个内部类Project,用于根据项目的热度值对开源项目进行排序。

main方法首先读取开源项目的个数n和权重值列表,然后读取每个项目的统计维度并计算每个项目的热度值。使用内部类Project来存储项目名和计算得到的热度值。

Project内部类包含项目名name和热度值hot两个字段,以及相应的构造方法。

接下来,使用Arrays.sort对项目数组进行排序,排序规则是:首先根据热度值降序排序,如果热度值相同,则根据项目名全小写后的字典序排序。

最后,遍历排序后的项目数组并打印出每个项目的名称。

package OD351;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @description 转盘寿司
 * @level 5
 * @type 数据结构、栈、单调栈
 */

/**
 * 题目描述
 * 寿司店周年庆,正在举办优惠活动回馈新老客户。
 * <p>
 * 寿司转盘上总共有 n 盘寿司,prices[i] 是第 i 盘寿司的价格,
 * <p>
 * 如果客户选择了第 i 盘寿司,寿司店免费赠送客户距离第 i 盘寿司最近的下一盘寿司 j,前提是 prices[j] < prices[i],如果没有满足条件的 j,则不赠送寿司。
 * <p>
 * 每个价格的寿司都可无限供应。
 * <p>
 * 输入描述
 * 输入的每一个数字代表每盘寿司的价格,每盘寿司的价格之间使用空格分隔,例如:
 * <p>
 * 3 15 6 14
 * <p>
 * 表示:
 * <p>
 * 第 0 盘寿司价格 prices[0] 为 3
 * 第 1 盘寿司价格 prices[1] 为 15
 * 第 2 盘寿司价格 prices[2] 为 6
 * 第 3 盘寿司价格 prices[3] 为 14
 * 寿司的盘数 n 范围为:1 ≤ n ≤ 500
 * <p>
 * 每盘寿司的价格 price 范围为:1 ≤ price ≤ 1000
 * <p>
 * 输出描述
 * 输出享受优惠后的一组数据,每个值表示客户选择第 i 盘寿司时实际得到的寿司的总价格。使用空格进行分隔,例如:
 * <p>
 * 3 21 9 17
 */
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //将接受到的数据用空格分隔,并转为整型数组
        int[] prices = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        int[] newPrices = getDiscount(prices);
        Arrays.stream(newPrices).forEach(price -> System.out.print(price + " "));
    }

    //返回享受一轮优惠后的寿司价格
    public static int[] getDiscount(int[] prices) {
        int[] newPrices = new int[prices.length];

        //newPrices[i] = prices[i] + 第一个比自己少的prices
        newPrices = Arrays.copyOfRange(prices, 0, prices.length);

        //每一个往后遍历,遇到第一个价格比自己低的,则+=
        for (int i = 0; i < prices.length; i++) {
            //标记是否找到比自己价格低的
            boolean flag = false;
            //先从i+1往后遍历
            for (int j = i + 1; j < prices.length; j++) {
                //从i往后遍历,找到第一个比自己价格低的
                if (prices[j] < prices[i] && !flag) {
                    newPrices[i] += prices[j];
                    flag = true;
                    break;
                }
            }
            //如果往后遍历没找到,则从开头往i-1遍历
            if (!flag) {
                for (int k = 0; k < i; k++) {
                    if (prices[k] < prices[i]) {
                        newPrices[i] += prices[k];
                        flag = true;
                        break;
                    }
                }
            }
        }
        return newPrices;
    }
}
package OD352;

import java.util.Arrays;
import java.util.Scanner;

/**
 * @description 开源项目热度榜单
 * @level 3
 * @type 多条件排序
 * @score 100
 * @url https://hydro.ac/d/HWOD2023/p/OD352
 */

/**
 * 题目描述
 * <p>
 * 某个开源社区希望将最近热度比较高的开源项目出一个榜单,推荐给社区里面的开发者。
 * 对于每个开源项目,开发者可以进行关注(watch)、收藏(star)、fork、提issue、提交合并请求(MR)等。
 * 数据库里面统计了每个开源项目关注、收藏、fork、issue、MR的数量,开源项目的热度根据这5个维度的加权求和进行排序。
 * H = W(watch) x #watch + W(star) x #star + W(fork) x #fork + W(issue) x #issue + W(mr) x #mr
 * H 表示热度值
 * W(watch)、W(star)、W(fork)、W(issue)、W(mr) 分别表示5个统计维度的权重
 * #watch、#star、#fork、#issue、#mr 分别表示5个统计维度的统计值
 * 榜单按照热度值降序排序,对于热度值相等的,按照项目名字转换为全小写字母后的字典序排序('a','b','c',...,'x','y','z')。
 * <p>
 * 输入描述
 * 第一行输入为N,表示开源项目的个数,0 < N <100。
 * <p>
 * 第二行输入为权重值列表,一共 5 个整型值,分别对应关注、收藏、fork、issue、MR的权重,权重取值 0 < W ≤ 50。
 * <p>
 * 第三行开始接下来的 N 行为开源项目的统计维度,每一行的格式为:
 * <p>
 * name nr_watch nr_start nr_fork nr_issue nr_mr
 * <p>
 * 其中 name 为开源项目的名字,由英文字母组成,长度 ≤ 50,其余 5 个整型值分别为该开源项目关注、收藏、fork、issue、MR的数量,数量取值 0 < nr ≤ 1000。
 * <p>
 * 输出描述
 * 按照热度降序,输出开源项目的名字,对于热度值相等的,按照项目名字转换为全小写后的字典序排序('a' > 'b' > 'c' > ... > 'x' > 'y' > 'z')。
 */
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    //自定义类 项目名 总热度
    static class Project {
        String name;
        int hot;

        public Project(String name, int hot) {
            this.name = name;
            this.hot = hot;
        }
    }


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        //开源项目个数
        int n = Integer.parseInt(sc.nextLine());
        //权重值列表 大小固定为5
        int[] weights = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

        Project[] projects = new Project[n];

        //项目名 和各项分 最后统计总分
        for (int i = 0; i < n; i++) {
            String name = sc.next();
            //总热度值
            int hot = 0;
            for (int j = 0; j < 5; j++) {
                hot += sc.nextInt() * weights[j];
            }
            projects[i] = new Project(name, hot);
        }

        //排序:先按总热力值降序,相同则按转小写后的项目名字排序
        Arrays.sort(projects, (a, b) -> {
            if (a.hot != b.hot) return b.hot - a.hot;
            else return a.name.toLowerCase().compareTo(b.name.toLowerCase());
        });

        //打印
        for (Project project : projects) {
            System.out.println(project.name);
        }
    }
}
  • 17
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值