acm寒假集训第二讲总结
1.二分查找
思路:
使用二分法查找答案即可
代码:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int q;
cin>>q;
for(int i=0;i<q;i++)
{
int x,l=0,r=n-1,is=0;
cin>>x;
while(r>=l)
{
int mid=(l+r)/2;
if(a[mid]==x)
{
cout<<"Yes"<<endl;
is=1;
break;
}
else if(a[mid]>x)
{
r=mid-1;
}
else if(a[mid]<x)
{
l=mid+1;
}
}
if(is==0)
{
cout<<"No"<<endl;
}
}
return 0;
}
2.A-B 数对
思路:
A-B=C相对于A=B+C,遍历所有可行的B得出A并用二分法查找,先要将输入进行排序,排序后查找对每个确定的B对应的第一个A和最后一个A的位置即可得出有几个A
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
long long int n,c,cnt=0;
cin>>n>>c;
long long int arry[n];
for(long long int i=0;i<n;i++)
{
cin>>arry[i];
}
sort(arry,arry+n);
long long int a,b=arry[0];
a=b+c;
for(long long int i=1;i<n&&a<=arry[n-1];i++)
{
long long int p1,p2;
long long int l1,r1,l2,r2,mid1,mid2,ans1,ans2;
l1=l2=0;r1=r2=n-1;
while(l1<=r1)
{
mid1=(l1+r1)/2;
if(arry[mid1]>=a)
{
r1=mid1-1;
ans1=mid1;
}
else l1=mid1+1;
}
p1=ans1;
while(l2<=r2)
{
mid2=(l2+r2)/2;
if(arry[mid2]<=a)
{
l2=mid2+1;
ans2=mid2;
}
else r2=mid2-1;
}
p2=ans2;
cnt+=p2-p1+1;
b=arry[i];
a=b+c;
}
cout<<cnt;
return 0;
}
3.分巧克力
思路:
首先找到巧克力中的最长边长(不一定要用到每块巧克力),1~最长边长就是答案区间,具有单调性,使用二分法查找符合条件中最大的即可
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
struct date
{
long long int x,y;
};
int check(long long int x,struct date *a,long long int n,long long int k);
int main()
{
long long int n,k,i,j;
cin>>n>>k;
struct date a[n];
long long int b[2*n];
for(i=0,j=0;i<n,j<2*n;i++,j+=2)
{
cin>>a[i].x>>a[i].y;
b[j]=a[i].x;b[j+1]=a[i].y;
}
sort(b,b+2*n);
long long int ar[b[2*n-1]];
for(i=0;i<b[2*n-1];i++)
{
ar[i]=i+1;
}
long long int l,r,mid,ans;
l=0;r=b[2*n-1]-1;
while(l<=r)
{
mid=(l+r)/2;
if(check(ar[mid],a,n,k))
{
l=mid+1;
ans=mid;
}
else
{
r=mid-1;
}
}
cout<<ans+1;
return 0;
}
int check(long long int x,struct date *a,long long int n,long long int k)
{
long long int cnt=0;
for(int i=0;i<n;i++)
{
cnt+=(a[i].x/x)*(a[i].y/x);
}
if(cnt>=k) return 1;
else return 0;
}
4.卡牌
思路:
计算最大的ai+bi,答案区间为0~max(ai+bi),使用二分法查找符合要求的最大值即可
代码:
#include <iostream>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std;
int check(long long int x,long long int *ai,long long int *bi,long long int n,long long int m);
int main()
{
long long int n,m,i;
cin>>n>>m;
long long int ai[n],bi[n];
for(i=0;i<n;i++)
{
cin>>ai[i];
}
for(i=0;i<n;i++)
{
cin>>bi[i];
}
long long int max=-1;
for(i=0;i<n;i++)
{
if(ai[i]+bi[i]>max)
{
max=ai[i]+bi[i];
}
}
long long int l,r,mid,ans;
l=0;r=max;
while(l<=r)
{
mid=(l+r)/2;
if(check(mid,ai,bi,n,m))
{
l=mid+1;
ans=mid;
}
else
{
r=mid-1;
}
}
cout<<ans;
return 0;
}
int check(long long int x,long long int *ai,long long int *bi,long long int n,long long int m)
{
long long int cnt=0;
for(long long int i=0;i<n;i++)
{
if(bi[i]<x-ai[i])
{
return 0;
}
if(ai[i]<x)
{
cnt+=(x-ai[i]);
}
}
if(cnt<=m) return 1;
else return 0;
}
学习总结:
通过这次的学习,我学习到了二分法的原理和基本模板,还学习了二分查找和二分答案,二分法有效提高了代码的效率,在讲解时也了解到了高效的代码实现方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)