代码来自大佬 Mine_King 的个人中心 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,k,a[100005];
int l,r,ans;
int check(int x)//这里直接模拟即可
{
int num=0,len=0;
for(int i=1;i<=n;i++)
{
num+=a[i];
if(num<0) num=0;
if(num>=x) num=0,len++;
}
return len;
}
signed main()
{
scanf("%lld%lld",&n,&k);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
l=1,r=1e15;
ans=1e15+1;
while(l<=r)//二分左边界
{
int mid=(l+r)/2;
if(check(mid)>k) l=mid+1;
else if(check(mid)<k) r=mid-1;
else ans=mid,r=mid-1;//***********************
}
if(ans!=1e15+1) printf("%lld ",ans);
//判断是否存在这样的区间
//如果 ans修改过 则存在答案
else
{
printf("-1 ");
return 0;
}
l=1,r=1e15;
ans=1e15+1;
while(l<=r)//二分右边界
{
int mid=(l+r)/2;
if(check(mid)>k) l=mid+1;
else if(check(mid)<k) r=mid-1;
else ans=mid,l=mid+1;//********************
}
printf("%lld\n",ans);
return 0;
}
这里的cheak 返回 个数用以判断对于k来说二分出的答案是大了还是小了从而进行调整
如果mid返回个数大于k说明门槛小了 所以mid要增大 让l=mid+1;
反之则相反
如果刚好返回个数等于k相等说明 当前mid是一个可行解 记录 并且缩小范围看是否存在
更小或者更大 的答案满足条件 求更小或更大 答案数用注释************的语句控制
直至求出答案
解题的两种做法
1.直接设计求解
2.枚举答案进行验证
这里二分答案 试一试是否满足 进行验证