【华为机考E卷】-“虚拟理财游戏”题解思路java

算法每一题,成长每一天~

C0E28 虚拟理财游戏

真题链接:【持续更新】2024华为 OD 机试E卷 机考真题库清单(全真题库)

思路

在这里插入图片描述

Java

import java.util.Scanner;

public class C0E28 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        String[] split = in.nextLine().split(" ");
        int n = Integer.parseInt(split[0]); // n个商品
        int A = Integer.parseInt(split[1]); // 总投入
        int R = Integer.parseInt(split[2]); // 总风险

        // 录入回报率
        int[] backs = new int[n];
        String[] split1 = in.nextLine().split(" ");
        for (int i = 0; i < n; i++) {
            backs[i] = Integer.parseInt(split1[i]);
        }

        // 录入风险
        int[] risks = new int[n];
        String[] split2 = in.nextLine().split(" ");
        for (int i = 0; i < n; i++) {
            risks[i] = Integer.parseInt(split2[i]);
        }

        // 录入投入量
        int[] amounts = new int[n];
        String[] split3 = in.nextLine().split(" ");
        for (int i = 0; i < n; i++) {
            amounts[i] = Integer.parseInt(split3[i]);
        }

        // 投入单个产品,计算其回报
        int[] singleBacks = new int[n];
        calcSingleBack(backs, risks, amounts, singleBacks, n, A, R);

        int maxBack = 0;
        int maxIdx = 0, maxAmount = 0;
        for (int i = 0; i < singleBacks.length; i++) {
            if (singleBacks[i] > maxBack) {
                maxBack = singleBacks[i];
                maxIdx = i;
                maxAmount = Math.min(A, amounts[i]);
            }
        }

        // 投入两个产品,计算回报
        int[] doubleBacks = new int[n * n / 2];  // 记录回报
        int[][] records = new int[doubleBacks.length][4]; // 记录组合信息: 0-产品1, 1-产品1数量, 2-产品2, 3-产品2数量
        calcDoubleBack(backs, risks, amounts, doubleBacks, records, n, A, R);

        int maxBack2 = 0;
        int maxIdx1 = 0, maxIdx2 = 0, maxAmount1 = 0, maxAmount2 = 0;
        for (int i = 0; i < doubleBacks.length; i++) {
            if (doubleBacks[i] > maxBack2) {
                maxBack2 = doubleBacks[i];
                maxIdx1 = records[i][0];
                maxAmount1 = records[i][1];
                maxIdx2 = records[i][2];
                maxAmount2 = records[i][3];
            }
        }

        // 输出
        if (maxBack > maxBack2) {
            for (int i = 0; i < n; i++) {
                if (i == maxIdx) {
                    System.out.print(maxAmount);
                } else {
                    System.out.print(0);
                }
                System.out.print(" ");
            }
        } else {
            for (int i = 0; i < n; i++) {
                if (i == maxIdx1) {
                    System.out.print(maxAmount1);
                } else if (i == maxIdx2) {
                    System.out.print(maxAmount2);
                } else {
                    System.out.print(0);
                }
                System.out.print(" ");
            }
        }
    }

    private static void calcSingleBack(int[] backs, int[] risks, int[] amounts, int[] singleBacks,
                                       int n, int A, int R) {
        for (int i = 0; i < n; i++) {
            if (risks[i] <= R) {
                int amount = Math.min(amounts[i], A); // 不能超过总投入
                singleBacks[i] = amount * backs[i]; // 投入 x 回报率
            }
        }
    }

    private static void calcDoubleBack(int[] backs, int[] risks, int[] amounts,
                                       int[] doubleBacks, int[][] records,
                                       int n, int A, int R) {
        int index = 0;
        // 嵌套for循环, 遍历所有可能的组合
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {

                if (risks[i] + risks[j] <= R) {
                    // 全量投入高回报的,剩余投入低回报的
                    int highIdx = i, lowIdx = j;
                    if (backs[i] < backs[j]) {
                        int temp = highIdx;
                        highIdx = lowIdx;
                        lowIdx = temp;
                    }

                    int highAmount = Math.min(amounts[highIdx], A);
                    int lowAmount = Math.min(amounts[lowIdx], A - highAmount);
                    int back = highAmount * backs[highIdx] + lowAmount * backs[lowIdx];

                    doubleBacks[index] = back;

                    records[index][0] = highIdx;
                    records[index][1] = highAmount;
                    records[index][2] = lowIdx;
                    records[index][3] = lowAmount;

                    index++;
                }
            }
        }
    }
}

总结

1、没什么特别的,就是数学逻辑 比较多,需要耐心。


算法要多练多练多练!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值