lower_bound()返回值是一个迭代器,返回指向大于key的第一个值的位置
使用:lower_bound(a,a+8,key)-a
upper_bound()返回值是一个迭代器,返回指向大于等于key的第一个值的位置
使用:upper_bound(a,a+8,key)-a
二分查找
#include
using namespace std;
int a[1000010];
int main()
{
int n,x;
while(cin>>n>>x)
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
printf("%d\n",lower_bound(a,a+n,x)-a);
}
return 0;
}
小清新的二倍问题加强版-二分-桶排
#include
using namespace std;
int main()
{
int n;
scanf("%d",&n);
for(int a=0; a<n; a++)
{
int x[100500]= {0},m,res=0,i;
for(i=1;; i++)
{
scanf("%d",&m);
if(m==0)
break;
else
x[m]=1;
}
for(int j=1; j<50250; j++)
{
if(x[j]==1&&x[j*2]==1)
res++;
}
printf("%d\n",res);
}
return 0;
}
小清新的二分查找之旅
#include
using namespace std;
int x[1000100];
int main()
{
int n,q;
while(scanf("%d%d",&n,&q)!=-1)
{
int y;
for(int i=1; i<=n; i++)
scanf("%d",&x[i]);
for(int i=1; i<=q; i++)
{
int res;
scanf("%d",&y);
res=upper_bound(x+1,x+1+n,y)-x-1;
if(x[res]==y)
printf("no\n");
else
printf("YES\n");
}
}
return 0;
}
小清新的函数坐标-二分
#include
using namespace std;
double f(double x);
int main()
{
double y;
while(scanf("%lf",&y)!=-1)
{
double l=-20.0,r=20.0,m,res;
while(l<r)
{
m=(l+r)/2.0;
if(r-l<1e-8)
break;
if(f(m)>y)
r=m;
else
l=m;
}
printf("%.4lf\n",m);
}
return 0;
}
double f(double x)
{
double res;
res=0.0001* pow(x,5) + 0.003 *pow(x,3) + 0.5 *x - 3.0;
return res;
}
小清新切绳子-二分
#include
using namespace std;
int check(int m);
int x[100000],n,k;
int main()
{
while(scanf("%d%d",&n,&k)!=-1)
{
int res=0;
for(int i=1; i<=n; i++)
scanf("%d",&x[i]);
int r=x[1],l=0,m;
for(int i=2; i<=n; i++)
if(r<x[i])
r=x[i];
while(l<=r)
{
m=(l+r)/2;
if(check(m)==1)
{
res=m;
l=m+1;
}
else
r=m-1;
}
printf("%d\n",res);
}
return 0;
}
int check(int m)
{
int res=0;
for(int i=1; i<=n; i++)
res=res+x[i]/m;
if(res>=k)
return 1;
else
return 0;
}
成绩查询
#include
using namespace std;
int main()
{
int n,k,min_b,max_b;
scanf("%d",&n);
double a[100005],minl,maxr;
for(int i=0; i<n; i++)
scanf("%lf",&a[i]);
sort(a,a+n);
while(~scanf("%lf%lf",&minl,&maxr))
{
min_b=lower_bound(a,a+n,minl)-a;
max_b=upper_bound(a,a+n,maxr)-a;
k=max_b-min_b;
printf("%d\n",k);
}
return 0;
}
这也是裸的找
#include
using namespace std;
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
int r=1,l=n,mid,res=0;
while(r<=l)
{
res++;
mid=(r+l)/2;
if(mid==k)
break;
if(mid<k)
r=mid+1;
else
l=mid-1;
}
printf("%d\n",res);
}
return 0;
}
数列分段-二分
#include
using namespace std;
int arr[100002];
int n, m;
int lef, rig, mid;
int tu, ts;
bool judge(int mid)//用来判别是否每一段都可以小于mid
{
for (int i=1;i<=n;i++)
{
if (tu+arr[i]<=mid)//如果还是小于mid,就继续加上去
tu+=arr[i];
else//否则就开启另一段,ts加一,并且设置tu为当前的数字
{
ts+=1;
tu=arr[i];
}
}
return ts>=m;
}
int main()
{
cin>>n>>m;
for (int i = 1; i <= n; i++)
{
cin>>arr[i];
rig+=arr[i];
lef=lef>arr[i]?lef : arr[i];
}
while(lef<=rig)
{
mid =(lef +rig)/2;
ts=tu=0;
if(judge(mid))//如果最后的ts是大于m的话,说明mid太小了,需要lef往右移
lef=mid+1;
else//否则就是mid太大了
rig=mid-1;
}
cout<<lef<<endl;
return 0;
}