【问题标题】:Truthful solution of binary search task二分查找任务的真解
【发布时间】:2021-08-30 01:30:43
【问题描述】:

我无法解决基于基础计算机科学的任务。起初我用线性递减的方法做解决方案,但它花费了很多时间,而且解决方案没有通过任务平台的测试。然后我将代码重构为二进制搜索。一切都很好,但这个解决方案没有通过测试——其中一个有错误的答案。未显示错误答案的全部原因 - 仅显示“错误答案”消息。请帮助我的代码中的逻辑有什么问题。

任务:

某公司的董事准备将奖金分配给该公司的所有经理。分配条件必须是:

  1. 所有经理的奖金应该相等
  2. 奖金应尽可能高
  3. 奖金必须是整数
  4. 奖金必须在一笔交易中为每位经理从一个账户发放,不得使用多个账户发送单一奖金

董事开了N个公司账户,账户上有不同数量的Cn钱,M个经理在公司工作。有必要在考虑条件的情况下找出可以发送的最大奖金金额。如果公司账户上没有足够的钱来发放至少1美元的红利,那么就没有红利了,你需要提取0。

输入数据(在标准输入流中接收) 第一行是整数N和M,用空格隔开(1≤N≤100 000, 1≤M≤100 000) 那么有N行,每行有一个整数Cn(0≤Cn≤100 000 000) 不需要检查输入数据和处理输入不正确的数据,验证的测试数据保证符合上述描述

输出数据(在标准输出流中预期)必须是一个整数值,最大可能的红利

示例 1 输入:

4 6

199

453

220

601

输出: 200

示例 2 输入:

2100

99

1

输出: 1

示例 3 输入:

2100

98

1

输出: 0

我的解决方案:

    import java.util.Scanner;
    
    public class Main {
        private static int managerCount;
        private static int[] accountMoney;
        private static int sum = 0;
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            String firstLine = sc.nextLine();
            String[] firstLineArray = firstLine.split(" ");
    
            int accountCount = Integer.parseInt(firstLineArray[0]);
            accountMoney = new int[accountCount];
            managerCount = Integer.parseInt(firstLineArray[1]);
    
            for (int i = 0; i < accountCount; i++) {
                accountMoney[i] = Integer.parseInt(sc.nextLine());
                sum += accountMoney[i];
            }
            System.out.println(getValue());
        }
    
        private static boolean isNear(int salary, int managerCnt) {
            for (Integer v : accountMoney) {
                int totalSum = v;
                if (totalSum >= salary && managerCnt > 0) {
                    managerCnt -= totalSum / salary;
                }
            }
            return managerCnt <= 0;
        }
    
        private static int getValue() {
            int highLimit = sum / managerCount;
            int halfPart = highLimit;
            int lowLimit = 0;
            boolean isNear;
            boolean isNextNear;
            while (halfPart > 0) {
                isNear = isNear(halfPart, managerCount);
                isNextNear = isNear(halfPart + 1, managerCount);
                if (isNear && !isNextNear) {
                    break;
                }
                if (lowLimit == highLimit) {
                    halfPart = halfPart == lowLimit ? 0 : lowLimit;
                } else if (isNear) {
                    lowLimit = halfPart + 1;
                    halfPart = (lowLimit + highLimit) / 2;
                } else if (!isNextNear) {
                    highLimit = halfPart - 1;
                    halfPart = (lowLimit + highLimit) / 2;
                }
            }
            return halfPart;
        }
}

【问题讨论】:

    标签: java algorithm binary-search


    【解决方案1】:

    您可能想修改如何实现binary search

    您的 getValue 函数应更改为:

    private static int getValue() {
        int highLimit = sum / managerCount;
        int lowLimit = 0;
        int halfPart;
        boolean isNear;
        while (highLimit > lowLimit) {
            halfPart = lowLimit + (highLimit - lowLimit + 1) / 2;
            if (isNear(halfPart, managerCount)) {
                lowLimit = halfPart;
            } else {
                highLimit = halfPart - 1;
            }
        }
        return lowLimit;
    }
    

    【讨论】:

    • 虽然嘲笑非英语母语人士很有趣(不,不是) - 这是冒犯和不恰当的。有很多更好的方法来纠正某人。请删除此答案的攻击性标题。
    • 非常感谢您的回答,对不起我的英语。现在我了解了二进制搜索实现的正确方法。但是现在该任务没有通过消息“超出内存限制”得到批准。可能你能给出建议,如何让它更快,可能它不会是二分搜索算法?
    • @amit,对不起,我不是有意冒犯。我自己不是母语人士。我已经删除了标题。
    • @MichaelStrelchenko 请不要贬低它,我的意思是对语言错误没有冒犯。我经常自己提交。
    • @MichaelStrelchenko 内存限制是什么问题?
    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 2015-12-10
    • 1970-01-01
    • 2016-01-14
    • 2021-03-07
    • 1970-01-01
    • 2018-03-27
    相关资源
    最近更新 更多