Search code examples
javaalgorithmbinary-search

Truthful solution of binary search task


I can't solve the task based in the basic computer science. At first I made solution with linear decrement but it costs much time and the solution didn't pass the tests of task platform. Then I refactored code to binary search. All is fine but this solution doesn't pass tests - there is wrong answer in one of them. The full cause of wrong answer is not shown - only message "Wrong answer". Help please with adwise what is wrong with logic in my code.

The task:

The director of some company is going to distribute the bonus to all managers of the company. The conditions of distribution must be:

  1. the bonus should be equal for all managers
  2. the bonus should be maximum as possible
  3. the bonus must be integer
  4. the bonus must be issued in one transaction from one account for each manager, without using multiple accounts to send a single bonus

The director has N corporate accounts open, on which there are different amounts of Cn money, and M managers work in the company. It is necessary to find out the maximum amount of the bonus that can be sent taking into account the conditions. If there is not enough money on the company's accounts to issue a bonus of at least 1 USD, then there will be no bonus, and you need to withdraw 0.

Input data (received in the standard input stream) The first line is integers N and M separated by a space (1≤N≤100 000, 1≤M≤100 000) Then there are N lines, each of which has one integer Cn (0≤Cn≤100 000 000) Checking the input data and processing incorrect data at the input is not necessary, the test data for verification is guaranteed to fit the description above

Output data (expected in the standard output stream) must be one integer value, the maximum possible bonus

Example 1 Input:

4 6

199

453

220

601

Output: 200

Example 2 Input:

2 100

99

1

Output: 1

Example 3 Input:

2 100

98

1

Output: 0

My solution:

    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;
        }
}

Solution

  • You might want to revise how to implement a binary search:

    Your getValue function should be changed to:

    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;
    }