File Modal
int Binary_Search(int lim,int rim) {
int mid;
while(l<r){
mid=(l+r+1)>>1;
if(check(mid)){
l=mid;
}else{
r=mid-1;
}
}
return l;
}
int Binary_Search(int lim,int rim) {
int mid;
while(l<r){
mid=(l+r)>>1;
if(check(mid)){
r=mid;
}else{
l=mid+1;
}
}
return l;
}
double Binary_Search(double lim,double rim){
double mid;
while(rim-lim>eps){
mid=(lim+rim)/2;
if(check(mid)){
l=mid;
}else{
r=mid;
}
}
return l;
}
Question 01 [ACP2036 数列分段]
注意组数从一开始!
需要特判有单个元素大于 lim!
Code
#include<bits/stdc++.h>
using namespace std;
const int N=1999940;
int n,m;
long long lable[N],tot;
bool check(long long lim){
int ans=1;
long long cnt=0;
for(int i=1;i<=n;i++){
if(lable[i]>lim)return false;
if(cnt+lable[i]>lim)cnt=0,++ans;
cnt+=lable[i];
}
return ans<=m;
}
long long ans(long long lim,long long rim){
long long mid;
while(lim<rim){
mid=(lim+rim)/2;
if(check(mid)){
rim=mid;
}else{
lim=mid+1;
}
}
return rim;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&lable[i]),tot+=lable[i];
printf("%lld",ans(0,tot));
return 0;
}
Question 02 [ACP1902 最短跳跃距离]
注意去掉离起点和终点一倍间距内的石头!
Code
#include<bits/stdc++.h>
using namespace std;
const int N=50009;
int l,n,m,lable[N];
bool check(int lim){
int np=0,kill=0,st=1,ed=n;
while(st<=n&&lable[st]<lim)++st,++kill;
while(ed>=1&&l-lable[st]<lim)--ed,++kill;
np=lable[st];
for(int i=st+1;i<=ed;i++){
if(lable[i]-np<lim)kill++;
else np=lable[i];
}
return kill<=m;
}
int ans(int lim,int rim){
int mid;
while(lim<rim){
mid=(lim+rim+1)>>1;
if(check(mid)){
lim=mid;
}else{
rim=mid-1;
}
}
return lim;
}
int main(){
scanf("%d%d%d",&l,&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&lable[i]);
printf("%d",ans(1,l));
return 0;
}
Question 03 [ACP2043 愤怒的牛]
二分答案模板题
Code
#include<bits/stdc++.h>
using namespace std;
const int N=150009;
int n,m,lable[N];
inline bool check(int distance){
int np=lable[1],cow=1;
for(int i=2;i<=n;i++){
if(lable[i]-np>=distance){
++cow,np=lable[i];
}
}
return cow>=m;
}
int ans(int lim,int rim){
int mid;
while(lim<rim){
mid=(lim+rim+1)>>1;
if(check(mid)){
lim=mid;
}else{
rim=mid-1;
}
}
return lim;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&lable[i]);
sort(lable+1,lable+n+1);
printf("%d",ans(1,lable[n]-lable[1]));
return 0;
}
Question 04 [ACP2044 Best Cow Fences]
给定一个长度为n的正整数序列A,求一个平均数最大的,长度不小于L的子串
Answer
本题集毒瘤毒瘤和毒瘤于一身,令人RP--
首先本题为01规划问题
即要求收益比代价的值最大
定义收益数组V,代价数组W
V[1]+V[2]+v[3]+...+V[n]
设-------------------------- =ans (其中可能有不选的,ans为理想值)
W[1]+w[2]+w[3]+...+W[n]
去分母得
ans*W[1]+ans*W[2]+...+ans*W[n]=V[1]+V[2]+...+V[n]
(V[1]-ans*W[1])+(V[2]-ans*W[2])+...+(V[n]-ans*W[n])=0
易知在本题中W[i]=1
(因为求平均数每个数的加入都会使分母加一)
所以
(V[1]-ans)+(V[2]-ans)+...+(V[n]-ans)=0
我们想要找是否有长度足够且符合该条件的字段
定义 (V[i]-ans) 为 delta[i]
问题转为 delta 长度大于等于 L 的最大正字段和
使用前缀和求解即可
注意实数二分且直接取整本题要取 rim
example
lim=4.999999999999999 -> 4999
rim=5.000000000000001 -> 5000
Code
#include<bits/stdc++.h>
using namespace std;
const int N=150009;
const double eps=1e-9;
int n,m,lable[N],tot;
double delta[N];
bool check(double average){
for(int i=1;i<=n;i++)delta[i]=(double)lable[i]-average+delta[i-1];
double mini=0.0,answer=-1.0;
for(int i=1,j=m;j<=n;i++,j++) {
answer=max(delta[j]-mini,answer);
mini=min(mini,delta[i]);
}
if(answer>0)return true;
return false;
}
double ans(double lim,double rim){
double mid;
while(rim-lim>eps){
mid=(lim+rim)/2.0;
if(check(mid)){
lim=mid;
}else{
rim=mid;
}
}
return rim*1000;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>lable[i],tot+=lable[i];
cout<<(int)ans(0.0,tot);
return 0;
}
Question 05 [ACP2045 曲线]
有 k 个二次函数 f(x)=ax^2+bx+c (0<=a<=1000)
ff(x)=max(所有 f(x))
求ff(x)在[0,1000]上的最大值
Answer
易知 ff 在[0,1000]上[单调递增/有单峰]
三分模板
Code
#include<bits/stdc++.h>
using namespace std;
const int N=19994;
const double eps=1e-8;
int n,a[N],b[N],c[N];
double mid1,mid2,lim,rim,ans;
double M(double x){
double ans=-1e10;
for(int i=1;i<=n;i++)ans=max(ans,(double)a[i]*x*x+(double)+b[i]*x+(double)c[i]);
return ans;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d%d",&a[i],&b[i],&c[i]);
lim=0,rim=1000;
while(rim-lim>eps){
mid1=lim+(rim-lim)/3.0,mid2=rim-(rim-lim)/3.0;
if(M(mid1)<=M(mid2))rim=mid2;else lim=mid1;
}
ans=M((lim+rim)/2.0);
printf("%.4lf\n",ans);
}
return 0;
}

Question 06 [ACP2048 灯泡]
三分+推式子
Code
#include<bits/stdc++.h>
using namespace std;
const int N=199994;
double H,h,D;
inline double f(double k){return D-k+H-(D*H-D*h)/k;}
double ans(double lim,double rim){
double m1,m2;
while(rim-lim>1e-9){
m1=(lim*2.0+rim)/3.0,m2=(rim*2.0+lim)/3.0;
if(f(m1)>f(m2))rim=m2;else lim=m1;
}
return f(lim);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%lf%lf%lf",&H,&h,&D);
printf("%.3lf\n",ans(D-h*D/H,D));
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验