当前位置: 首页 > news >正文

2025年大一ACM训练-二分

2025年大一ACM训练-二分NEFU

折半查找 动画演示 完整代码 二分查找 binary search 数据结构与算法

A:二分查找

Problem A:
在这里插入图片描述

直接线性查找也可以,写一个二分搜索练手

#include<bits/stdc++.h>
using namespace std;
int main()
{long long n,x;int r,l,mid;while(cin>>n>>x){int num[n];for(int i=0;i<n;i++) cin>>num[i];l=0;r=n-1;while(true){mid=(l+r)/2;if(num[r]>x && num[r-1]<=x){cout<<r<<endl;break;}if(num[mid]<=x) l=mid;else r=mid;}}return 0;
}

B:卖古董-DP-二分

Problem B:
在这里插入图片描述

题目、算法都不难,作为二分专练,问题在于看出来这题哪里二分了。二分思路是 [ 单个最大值 ,整体的和 ] 以在划分区域内的价格为二分的对象。看出这个题目就简单了。

#include <bits/stdc++.h>
using namespace std;
int t,n,m,i,l,r,mid,sum,ans,tmpmax,a[100001];
bool judge(int mid)
{int s=0,cnt=1;for(i=1;i<=n;i++){s=s+a[i];if(s>mid){s=a[i];cnt++;}}return cnt>m;
}
int main()
{ios::sync_with_stdio(false);cin>>t;while(t--){cin>>n>>m;tmpmax=sum=0;for(i=1;i<=n;i++){cin>>a[i];tmpmax=max(tmpmax,a[i]);sum=sum+a[i];}l=tmpmax;r=sum;while(l<=r){mid=l+(r-l)/2;if(judge(mid))l=mid+1;else{ans=mid;r=mid-1;}}printf("%d\n",ans);}return 0;
}

C:二分查找加强版

Problem C:
在这里插入图片描述

和A相比就多了个排序

#include<bits/stdc++.h>
using namespace std;
int main()
{long long n,x;int r,l,mid;while(cin>>n>>x){int num[n];for(int i=0;i<n;i++) cin>>num[i];sort(num,num+n);l=0;r=n-1;while(true){mid=(l+r)/2;if(num[r]>x && num[r-1]<=x){cout<<r<<endl;break;}if(num[mid]<=x) l=mid;else r=mid;}}return 0;
}

D:小清新的函数坐标-二分

Problem D:
在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
double f(double x)
{return 0.0001*pow(x,5)+0.003*pow(x,3)+0.5*x-3;
}
int main()
{double x,y;while(scanf("%lf",&y)!=-1){double l=-20,r=20,mid,delta=99999;while(l<=r){mid=l+(r-l)/2;if(abs(mid-jl)<0.00001) break;if(f(mid)<y) l=mid;if(f(mid)>y) r=mid;delta=mid;}printf("%.4lf\n",mid);}return 0;
}

delta是必要的,控制精度,不然会一直细分容易死循环(因为我控制 r = mid 而不是 r = mid +1)误差越来越小了,但有些数据不能恰好对上,就会一直循环。

E:小清新的二分查找之旅

Problem E:
在这里插入图片描述

用cin,cout不得行,会超时。scanf和cin是两种常用的输入方式。通常情况下,scanf的效率要高于cin
①scanf是C语言中的函数,它直接操作指针,没有类型安全机制。例如,一个char类型的数据可以用%f来获取输入,而不会报错。而cin是C++中的输入流对象,它会自动判断变量类型,这增加了额外的开销。
②其cin为了与C语言的标准输入输出流(如stdin和stdout)保持同步,继承体系复杂,导致效率较低。在默认情况下,cin和cout会与C的标准输入输出流同步,这样可以防止混用时发生混乱,但也因此增加了额外的开销。
为了提高cin的效率,可以使用以下两种方法:
使用std::ios::sync_with_stdio(false);关闭与C标准输入输出流的同步
使用std::cin.tie(nullptr);解除cin和cout之间的绑定

#include<bits/stdc++.h>
using namespace std;
int n,q,k,a[1000001];
int main()
{while(scanf("%d%d",&n,&q) != EOF){for(int i=1; i<=n; i++)scanf("%d",&a[i]);for(int i=1; i<=q; i++){scanf("%d",&k);int l=1, r=n, mid;bool flag=false;while(l<r){mid = (l+r)/2;if(a[mid] < k) l = mid+1;else r = mid;if(a[mid]==k){flag = true;break;}}if(flag) printf("no\n");else printf("YES\n");}}return 0;
}

F:小清新的二倍问题加强版-二分-桶排

Problem F:
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
int a[200005]={0};
int main()
{int n;scanf("%d",&n);while(n--){int t,i=0,flag=0,maxx=0;do{scanf("%d",&t);if(t==0) break;a[t]++;if(a[t*2]==1) flag++;if(t%2==0&&a[t/2]==1) flag++;}while(1);printf("%d\n",flag);memset(a,0,sizeof(a));}return 0;
}

G:小清新切绳子-二分

Problem G:
在这里插入图片描述

#include <bits/stdc++.h>
#pragma GCC optimize(2)  //O2优化
using namespace std;
int l,r,n,m,k,ans,a[10001];
bool judge(int m)
{int s=0;for(int i=1;i<=n;i++) s=s+a[i]/m;return s>=k;
}
int main()
{ios::sync_with_stdio(false);while(cin>>n>>k){for(int i=1;i<=n;i++) cin>>a[i];l=0,r=10000000;while(l<=r){m=l+(r-l)/2;if(judge(m))ans=m,l=m+1;else r=m-1;}printf("%d\n",ans);}return 0;
}

H:书的复制-dp-二分

Problem:
这里是引用

#include<bits/stdc++.h>
using namespace std;
long long m,k;
long long a[505];
int x[505],y[505];
bool judge(int s) 
{int num=1,t=0;for(int i=m;i>=1;i--){if(t+a[i]>s) t=0,num++;t+=a[i];}return num<=k;
}
int find(int low,int high)
{int mid;while(low+1<high){mid=low+(high-low)/2;if(judge(mid)) high=mid;else low=mid;} return high;
}
int main()
{long long low=0,high=0;cin>>m>>k;for(int i=1;i<=m;i++){cin>>a[i];high+=a[i];low=max(low,a[i]);}int s=find(low,high);int t=0,num=1;for(int i=1;i<=k;i++) x[i]=y[i]=0;y[1]=m;for(int i=m;i>=1;i--){if(t+a[i]>s){t=0;x[num]=i+1;y[++num]=i;}t+=a[i];}x[num]=1;for(int i=k;i>=1;i--) cout<<x[i]<<" "<<y[i]<<endl;return 0;
}

I:数列分段-二分

Problem I:
这里是引用

#include <bits/stdc++.h>
using namespace std;
int k,n,a[100005];
int judge(int x)
{int sum=0;int i,flag=1;for(i=1; i<=n; i++){if(a[i]>x) return 0;sum+=a[i];if(sum>x){flag++;sum=a[i];}}return flag<=k;
}
int main()
{while(scanf("%d%d",&n,&k)!=-1){int i,sum=0;for(i=1; i<=n; i++){scanf("%d",&a[i]);sum+=a[i];}int low=0,high=sum,mid,ans=0;while(low<=high){mid=(low+high)>>1;if(judge(mid)==1){ans=mid;high=mid-1;}else low=mid+1;}printf("%d\n",ans);}return 0;
}

J:切绳子实数版-二分

Problem J:
在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10;
double x,ans;
int n,k,l,r,m,a[N];
bool judge(int m)
{int s=0;for(int i=1;i<=n;i++) s=s+a[i]/m;return s>=k;
}
int main()
{ios::sync_with_stdio(false);while(cin>>n>>k){for(int i=1;i<=n;i++){cin>>x;a[i]=(int)(x*100);  //精度不够,乘法来凑}l=0,r=1e7;while(l<=r){m=l+(r-l)/2;if(m==0){ans=0;break;}if(judge(m))ans=1.0*m,l=m+1;else r=m-1;}printf("%.2lf\n",ans/100.0);}return 0;
}

相关文章:

  • TCP协议详细讲解及C++代码实例
  • 欧拉计划 Project Euler 71(有序分数)题解
  • OPC UA 协议介绍
  • Antd中Form详解:
  • volatile是什么
  • # YOLOv3:基于 PyTorch 的目标检测模型实现
  • RevIN(Reversible Instance Normalization)及其在时间序列中的应用
  • 软件测试服务公司分享:国产化适配测试的重要性和关键要素
  • paimon中批和流查看过去的快照的数据及变动的数据
  • OSCP备战-Kioptrix4详细教程
  • Python+1688 API 开发教程:实现商品实时数据采集的完整接入方案
  • Conda在powershell终端中无法使用conda activate命令
  • React百日学习计划-Grok3
  • 如何学习VBA_3.3.3 VBA程序写好后,如何进行调试,直到程序运行
  • 数据结构—(链表,栈,队列,树)
  • 重生之我是CSDN大佬
  • 在VirtualBox中安装虚拟机后不能全屏显示的问题及解决办法
  • 从零实现一个高并发内存池 - 1
  • [ctfshow web入门] web72
  • Linux精确列出非法 UTF-8 字符的路径或文件名
  • 运营平台/seo管理系统培训运营
  • 呼市网站制作招聘/关键字有哪些
  • 政府网站建设思路汇报/百度app下载安装官方免费下载
  • 预付网站建设费用会计分录/seo工作内容
  • 潍坊网站建设/网络推广是什么意思
  • 网站推广服务费会计分录怎么做/成都seo