分值的思想
二分查找与二分答案
OPJ
二分01 求最接近元素
用longlong
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
long long n;
long long a1[100005];
int m;
long long a2[10005];
int main( ){
scanf("%lld",&n);
for(int i=1;i<=n;i++){
scanf("%lld",&a1[i]);
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%lld",&a2[i]);
}
for(int i=1;i<=m;i++){
int left=1,right=n;
int mid=0;
while(left<right-1){
mid=(left+right)/2;
if(a1[mid]<a2[i]){
left=mid;
}
else{
//else{
right=mid;
}
}
//if(a1[mid]==a2[j]) printf("%lld
",mid);
if(a2[i]-a1[left]<=a1[right]-a2[i]){
printf("%lld
",a1[left]);
}
else printf("%lld
",a1[right]);
}
return 0;
}
核心部分
for(int i=1;i<=m;i++){
int left=1,right=n;
int mid=0;
while(left<right-1){
mid=(left+right)/2;
if(a1[mid]<a2[i]){
left=mid;
}
else{
//else{
right=mid;
}
}
二分02:求函数零点
浮点数的二分需要终止二分的条件,一般来说写到要求位数的下一位来终止
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iomanip>
using namespace std;
double f(double mid){
double ans=mid*mid*mid*mid*mid-15*mid*mid*mid*mid+85*mid*mid*mid-225*mid*mid+274*mid-121;
return ans;
}
double k,midd;
int main( ){
double left=1.5,right=2.4;
while(left<right-0.0000001){
midd=(left+right)/2;
if(f(midd)<0){
right=midd;
}
if(f(midd)>0){
left=midd;
}
if(f(midd)==0){
k=midd;
printf("%.6lf",k);
return 0;
}
}
printf("%.6lf",midd);
return 0;
}
三分
对非单调性而有两段单调性的函数,可以进行列表排除
对二次函数的最值点进行求值,针对对称轴与区间的位置进行二分
注意的是,取三等分点的写法
(t_1=l+frac{1}{3}(r-l))
(t_2=l+frac{2}{3}(r-l))
二分的(mid=frac{l+r}{2})只是化简后的结果巧合
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-7;//其实一般精度*0.1=1e-6就可以了
int n;
double L,R;
double a[15];
//普通的求多项式
/*double F(double x)
{
double f=0;
for(int i=n;i>=0;i--)
{
double t=1;
for(int j=1;j<=i;j++)
t*=x;
f+=a[i]*t;
}
return f;
}*/
//秦九韶算法从里到外逐层计算一次多项式的值
double F(double x)
{
double sum=0;
for(int i=n;i>=0;i--)
sum=sum*x+a[i];
return sum;
}
int main()
{
cin>>n>>L>>R;
for(int i=n;i>=0;i--) cin>>a[i];
while(fabs(L-R)>=eps)
{
double mid=(L+R)/2;
if(F(mid+eps)>F(mid-eps)) L=mid;//舍弃左区间
else R=mid;//舍弃右区间
}
printf("%.5lf",R);
return 0;
}