样例一:
5 7
5 7 9 15 10
>> 9
样例二:
3 1
2 3 4
>> -1
解题思路
题目大概意思
: 给你N个数, 还有一个数M, 让你求K, 进行M次减K操作, 令这N个数都小于等于0。
思路
: 利用二分来快速找到K [N, sum(N)], 找到后去验证。如果验证能行, 区间向左聚, 如果不能向右聚。
sum(N)
: N个数的和。
Python题解【二分查找】O(nlogn)
import math
class Solution:
def check(self, target, nums, n):
"""
验证是否可行
"""
count = 0
for i in nums:
if i <= target:
count += 1
else:
count += math.ceil(i / target)
return True if count <= n else False
def run(self):
m, n = map(int, input().split(" "))
nums = list(map(int, input().split(" ")))
l, r = 0, sum(nums)
while l <= r:
mid = (l + r) >> 1 # 除二
if self.check(mid, nums, n):
r = mid - 1 # 向左聚合
else:
l = mid + 1 # 向右聚合
if l == -1 or l == sum(nums) + 1:
print(-1)
return
print(l)
if __name__ == '__main__':
Solution().run()
Java题解
import java.util.*;
public class Solution {
private boolean check(int target, int[] nums, int n) {
int count = 0;
for (int i : nums) {
if (i <= target) {
count += 1;
} else {
count += Math.ceil((double)i / target);
}
}
return count <= n;
}
public void run() {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
int[] nums = new int[m];
for (int i = 0; i < m; i++) {
nums[i] = scanner.nextInt();
}
int l = 0, r = Arrays.stream(nums).sum();
while (l <= r) {
int mid = (l + r) >> 1;
if (check(mid, nums, n)) {
r = mid - 1;
} else {
l = mid + 1;
}
}
if (l == -1 || l == Arrays.stream(nums).sum() + 1) {
System.out.println(-1);
return;
}
System.out.println(l);
}
public static void main(String[] args) {
new Solution().run();
}
}
Javascript题解
function check(target, nums, n) {
let count = 0;
for (let i of nums) {
if (i <= target) {
count += 1;
} else {
count += Math.ceil(i / target);
}
}
return count <= n;
}
function run() {
const input = readline().split(' ').map(Number);
const m = input[0];
const n = input[1];
const nums = readline().split(' ').map(Number);
let l = 0, r = nums.reduce((a, b) => a + b);
while (l <= r) {
let mid = (l + r) >> 1;
if (check(mid, nums, n)) {
r = mid - 1;
} else {
l = mid + 1;
}
}
if (l === -1 || l === nums.reduce((a, b) => a + b) + 1) {
console.log(-1);
return;
}
console.log(l);
}
run();
Go题解
package main
import (
"fmt"
"math"
)
func check(target int, nums []int, n int) bool {
count := 0
for _, i := range nums {
if i <= target {
count += 1
} else {
count += int(math.Ceil(float64(i) / float64(target)))
}
}
return count <= n
}
func main() {
var m, n int
fmt.Scanf("%d %d", &m, &n)
nums := make([]int, m)
for i := 0; i < m; i++ {
fmt.Scan(&nums[i])
}
l, r := 0, 0
for _, v := range nums {
r += v
}
for l <= r {
mid := (l + r) >> 1
if check(mid, nums, n) {
r = mid - 1
} else {
l = mid + 1
}
}
if l == -1 || l == r+1 {
fmt.Println(-1)
return
}
fmt.Println(l)
}