- 二分查找的作用是将O(n)的复杂度变成O(logn)
- mid = l+r >> 1 整数右移一位即相当于除以二
若为浮点数则写作(1+r)/2 - pi的定义:#define pi acos(-1.0)
- const double eps = 1e-6
while( l+eps<r ) eps指无限逼近
二分题目A:在1到100中寻找能满足制定式子的数,保留四位小数
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<cmath>//幂函数pow()头文件
const double eps=1e-6;
using namespace std;
int T;
double n;
double ans1;
bool check1(double x)
{
if(8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6.0>=n)
return 1;
else
return 0;
}
int main()
{
cin>>T;
while(T--)
{
cin>>n;//输入实数
if(n<6||n>8*pow(100,4)+7*pow(100,3)+2*pow(100,2)+3*100+6.0)
cout<<"No solution!"<<"\n";
else
{
double l=0.0,r=100.0;
while(l+eps<r)//l无限逼近于r
{
double mid=(l+r)/2;
if(check1(mid))
{
r=mid;
ans1=mid;
}
else
l=mid;
}
cout<<fixed<<setprecision(4)<<ans1<<"\n";//保留四位小数(fixed)的意思是若无零则自动补零
}
}
return 0;
}
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
const int maxn=1e6+9;
using namespace std;
int T,n,k;
int a[maxn];
int ans1;
bool check(int x)
{
int l=1,r=n;
while(l<r)
{
int mid=l+r>>1;
if(a[mid]==x) return 1;
else if(a[mid]>x)
r=mid;
else
l=mid+1;
}
return 0;
}
int main()
{
cin>>T;
while(T--)
{
memset(a,0,sizeof a);
ans1=0;
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n+1);
for(int i=1;i<=n;i++){
if(check(k-a[i]))
{
ans1++;
if(a[i]==a[i-1]&&i!=1)
ans1--;
}
}
cout<<ans1<<"\n";
}
return 0;
}
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#define pi acos(-1.0)
const int maxn=1e6+9;
const double eps=1e-6;
using namespace std;
int n,c;
int a[maxn];
bool check(int x)
{
int num=1,j=0;
for(int i=1;i<n;i++)
{
if(a[i]-a[j]>=x)
{
num++;
j=i;
}
}
if(num>=c)
return 1;
else
return 0;
}
int main()
{
int mid;
scanf("%d%d",&n,&c);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
int l=1,r=a[n-1]-a[0];//在最大值和最小值之间找一个最小值的最大值
while(l<r)
{
mid=l+r>>1;
int num=1,j=0;
if(check(mid))
l=mid+1;
else
r=mid;
}
cout<<r-1<<"\n";
return 0;
}
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iomanip>
#define pi acos(-1.0)
const int maxn=1e6+9;
using namespace std;
const double eps=1e-6;
double a[maxn];
int n,f,T;
double ans1;
bool check(double x)
{
int n1=0;
for(int i=0;i<n;i++)
{
n1+=(int)((a[i]*a[i]*pi)/x);
}
if(n1>=f+1)
return 1;
else
return 0;
}
int main()
{
cin>>T;
while(T--)
{
cin>>n>>f;
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);
double l=0,r=a[n-1]*a[n-1]*pi;//在最大体积和最小体积间找可能满足情况的体积
double ans1=0;
while(l+eps<r)//无限逼近
{
double mid=(l+r)/2;
if(check(mid))
{
l=mid;
ans1=mid;
}
else
r=mid;
}
cout<<fixed<<setprecision(4)<<ans1<<"\n";
}
return 0;
}
二分查找E:牛跳石头,在n块石头中取m块,再求最小值的最大值
#include<iostream>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
//#define pi acos(-1.0)
const int maxn=1e6+9;
const double eps=1e-6;
using namespace std;
int l,m,n,L;
int a[maxn];
int main()
{
cin>>L>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
a[0]=0;
a[n+1]=L;
sort(a,a+n+2);
int l=0,r=a[n+1];
while(l<=r)
{
int mid=l+r>>1;
int j=0,num=0;
for(int i=1;i<=n+1;i++)
{
if(a[i]-a[j]<=mid)//如果两个石头之间的距离小于mid则跳过
num++;
else
j=i;
}
if(num>m)
r=mid-1;
else
l=mid+1;
}
cout<<l<<endl;
return 0;
}