首页 > 其他 > 详细

二分与三分

时间:2019-12-05 22:58:33      阅读:85      评论:0      收藏:0      [点我收藏+]

分值的思想

二分查找与二分答案

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\n",mid);
            if(a2[i]-a1[left]<=a1[right]-a2[i]){
                printf("%lld\n",a1[left]);
            }
            else printf("%lld\n",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;
}

二分与三分

原文:https://www.cnblogs.com/liuziwen0224/p/11992405.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!