题意: 给出若干个木棍长度,你可以对每个木棍进行切割。
比如 有5个木棍,长度分别是4 4 4 5 3
你可以一次切长度为2的,那么4能切2刀,5能切2刀,3只能切一刀。总数加起来ans=2+2+2+2+1=9
题目问的就是一次切w刀,能使的ans>K.(K由题目给出),算出max(w)
数据范围:
n=2e5 木棍最大长度1e9
很显然这是一道二分的题目,二分一次切W刀,其实我们可以发现,最大切的次数应该是最大木棍长度,因为大于最大木棍长度没法切了嘛。
所以我们最大二分的区间是[1-1e9]
由于题目要最大值,我们只需要当ans>K的时候,记录最大值即可,注意二分的右边界需要+1,不然这组数据过不去
5 1
4 4 4 5 3
复杂度是n*logn
代码:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <cctype>
#include <cmath>
#include <cassert>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const ll mod=1000000007;
ll powmod(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
const int N=2e5+100;
ll a[N];
ll n,L;
int main()
{
scanf("%lld%lld",&n,&L);
ll maxx=-1e18;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
maxx=max(maxx,a[i]);
}
// if(L==1)
// {
// printf("%lld\n",maxx);
// return 0;
// }
ll l=1;
ll r=maxx+1;
ll res=-1e18;
while(l<r)
{
ll mid=(l+r)/2ll;
ll ans=0;
for(int i=1;i<=n;i++)
{
ans+=a[i]/mid;
}
//printf("mid:%lld ans:%lld\n",mid,ans);
if(ans<L)
{
r=mid;
}
else
{
res=max(res,mid);
l=mid+1;
}
}
if(res==-1e18)
{
printf("0\n");
}
else
{
printf("%lld\n",res);
}
return 0;
}

京公网安备 11010502036488号