我们考虑朴素算法,假设Max为给出木条的最大长度,直接枚举长度 0~Max,找到符合情况的最大值即可,由于最大长度可以为1e9,复杂度最差为O(1e9n)显然不行,观察发现,如果对于裁剪出长度为x的木条最多能凑出sum根,那么裁剪x+1长度的木条,肯定不会得到sum+1根,很明显,具有单调性,我们就能考虑二分。就像猜数字一个,每次猜一个数,判断能不能,如果符合,就可以往大的猜,如果不可以,就缩小。由于木条最大长度是1e9,所以二分复杂度为O(log1e9),对于判断,只需要遍历一遍全部木条即可,复杂度为O(n),总复杂度为O(nlog1e9)。
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <map>
#include<time.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
int n,m,A[maxn];
bool check(ll m1) {
if (m1==0) return true;
ll cnt=0;
for (int i=1; i<=n; i++) {
cnt+=A[i]/m1;
}
return cnt>=m;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++) {
scanf("%d",&A[i]);
}
ll l=0,r=1e9;
ll ans=0;
while (l<=r) {
ll m1=l+(r-l+1)/2;
if (check(m1)) {
l=m1+1;
ans=m1;
} else r=m1-1;
}
printf("%lld\n",ans);
return 0;
}



京公网安备 11010502036488号