题目描述
某软件系统会在运行过程中持续产生日志,系统每天运行 N 单位时间,运行期间每单位时
间产生的日志条数保行在数组 records 中。
records[i]表示第 i 单位时间内产生日志条数。
由于系统磁盘空间限制,每天可记录保存的日志总数上限为 total 条
如果一天产生的日志总条数大于 total,则需要对当天内每单位时间产生的日志条数进行限
流后保存,请计算每单位时间最大可保存日志条数 limit,以确保当天保存的总日志条数超
过 total。
对于单位时间内产生日志条数不超过 limit 的日志全部记录保存
对于单位时间内产生日志条数超过 limit 的日志,则只记录保存 limit 条日志;
如果一天产生的日志条数总和小于等于 total,则不需要启动限流机制,result 为-1.请返回
result 的最大值或者-1。
输入描述
第一行为系统某一天运行的单位时间数 N,1<=N<=10^5
第二行为表示这一天每单位时间产生的日志数量的数组 records[],0 <= records[i]<= 10^5
第三行为系统一天可以保存的总日志条数 total。1 <= total <= 10^9
输出描述
每单位时间内最大可保存的日志条数 limit,如果不需要启动限流机制,返回-1.
用例
输入
6
3 3 8 7 10 15
40
输出 9
二分查找
代码
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt();
int[] records = new int[N];
for (int i = 0; i < N; i++) {
records[i] = scanner.nextInt();
}
int total = scanner.nextInt();
int limit = calculateLimit(N, records, total);
System.out.println(limit);
}
public static int calculateLimit(int N, int[] records, int total) {
if (sum(records) <= total) {
return -1;
}
int left = 0;
int right = max(records);
int result = -1;
while (left <= right) {
int mid = (left + right) / 2;
int count = 0;
for (int i = 0; i < N; i++) {
count += Math.min(records[i], mid);
}
if (count > total) {
right = mid - 1;
} else {
result = mid;
left = mid + 1;
}
}
return result;
}
public static int sum(int[] arr) {
int sum = 0;
for (int num : arr) {
sum += num;
}
return sum;
}
public static int max(int[] arr) {
int max = Integer.MIN_VALUE;
for (int num : arr) {
if (num > max) {
max = num;
}
}
return max;
}
}
C++
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#include <algorithm>
#include <vector>
#include <time.h>
#include <bitset>
using namespace std;
vector<int> split(string str) {
vector<int> res;
while(str.find(' ')!=str.npos) {
int position=str.find(' ');
string tmp=str.substr(0,position);
res.push_back(stoi(tmp));
str=str.substr(position+1);
}
res.push_back(stoi(str));
return res;
}
int main() {
int N;
string str;
getline(cin,str);
N=stoi(str);
getline(cin,str);
vector<int> vec=split(str);
int sum=0;
for(int i=0;i<N;i++) {
sum+=vec[i];
}
int total;
cin>>total;
if(sum<=total) {
cout<<-1<<endl;
}else{
sort(vec.begin(),vec.end());
int low=vec[0];
int hi=vec[vec.size()-1];
int res;
while(hi>low+1) {
int pick=0;
int mid=(low+hi)/2;
for(int i=0;i<vec.size();i++) {
pick+=max(0,vec[i]-mid);
}
if(sum-pick>total) {
hi=mid;
}else if(sum-pick==total) {
res=mid;
break;
}else{
low=mid;
res=mid;
}
}
cout<<res<<endl;
}
system("pause");
return 0;
}
python
n=int(input())
vec=input().split()
arr=[]
copy=[]
sum=0
for i in vec:
arr.append(int(i))
copy.append(int(i))
sum+=int(i)
limit=int(input())
arr.sort()
low=arr[0]
hi=arr[-1]
res=0
while low<hi:
mid=int((low+hi)/2)
left=0
for i in range(len(arr)):
left+=min(arr[i],mid)
if left==limit:
res=mid
break
elif left<limit:
res=mid
low=mid+1
else:
hi=mid
if sum<=limit:
print(-1)
else:
print(res)