zoukankan      html  css  js  c++  java
  • 二分查找

    二分查找:

    例题一:

    题目来源:HDOJ-2199:Can you solve this equation?

    题目大意:给出一个方程8*x^4 + 7*x^3 + 2*x^2 + 3*x + 6 == Y,再给出一个Y。求出0~100之间的解。

    题目分析:最基础的二分查找问题。

    AC代码:

    #include <stdio.h>
    #include <math.h>
    double f(double x)
    {
           return 8*pow(x,4)+7*pow(x,3)+2*pow(x,2)+3*x+6;
    }
    double abs(double a)		//求绝对值
    {
           return a>0?a:-a;
    }
    int main()
    {
           int t;
           double y,left,right,mid;
           scanf("%d",&t);
           while(t--)
           {
                  scanf("%lf",&y);
                  if(y<f(0)||y>f(100))              //比較端点函数值
                  {
                         puts("No solution!");
                         continue;
                  }
                  else
                  {
                         left=0;right=100;
                         while(right-left>1e-8)     //对于double类型的值,应尽量减小误差
                         {
                                mid=(left+right)/2;
                                if(abs(f(mid)-y)<1e-8)
                                       break;
                                if((f(mid)-y)>1e-8)
                                       right=mid;
                                else
                                       left=mid;
                         }
                  }
                  printf("%.4lf
    ",mid);
           }    
           return 0;
    }


    例题二:

    题目来源:HDOJ-2141:Can you find it?

    题目大意:给你三个有序数列A, B, C,再给出一个数字 X. 是否能找到三个数字Ai, Bj, Ck, 使得 Ai+Bj+Ck = X.

    题目分析:最基础的二分查找问题。避免超时,进行优化,先合并两个数组再进行查找。

    AC代码:

    #include <stdio.h>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    #define C 550
    int L[C],N[C],M[C];
    int LN[C*C];
    int find(int LN[],int k,int y)           //二分查找
    {
           int left=0,right=k-1,mid;
           while(left<=right)
           {
                  mid=(left+right)/2;
                  if(LN[mid]==y)
                         return1;
                  if(LN[mid]>y)
                         right=mid-1;
                  else
                         left=mid+1;
           }
           return 0;
    }
    int main()
    {
           int l,n,m,s,i,j,k;
           int num=1,x,y,q;
           while(~scanf("%d%d%d",&l,&n,&m))
           {
                  k=0;
                  for(i=0;i<l;i++)
                         scanf("%d",&L[i]);
                  for(i=0;i<n;i++)
                         scanf("%d",&N[i]);
                  for(i=0;i<m;i++)
                         scanf("%d",&M[i]);
                  for(i=0;i<l;i++)
                         for(j=0;j<n;j++)
                                LN[k++]=L[i]+N[j];             //合并L和N
                  sort(LN,LN+k);            //对LN数组排序
                  scanf("%d",&s);
                  printf("Case %d:
    ",num++);
                  while(s--)
                  {
                         q=1;        // q为标记,1为找不到,0为能找到
                         scanf("%d",&x);
                         for(i=0;i<m;i++)
                         {
                                y=x-M[i];              //由于L+N+M=x。所以x-M=LN=y
                                if(find(LN,k,y))             //在LN数组中查找到y
                                {
                                       puts("YES");
                                       q=0;
                                       break;
                                }
                         }
                         if(q)        // 找不到y
                                puts("NO");
                  }
           }
           return 0;
    }


    例题三:

    题目来源:HDOJ-1551:Cable master

    题目大意:有n段长度不等的电缆。要求分成最大长度的k段长度相等的电缆

    题目分析:主要的二分查找,寻找最合适的长度。

    AC代码:

    #include <stdio.h>
    double a[100100];
    int n,k,i;
    bool find(double x)        //等长度的电缆段数是否符合要求,并且是否为最长的电缆
    {
           int sum=0;
           for(i=0;i<n;i++)
                  sum+=(int)(a[i]/x);
           return sum>=k;
    }
    int main()
    {
           double left,right,mid;
           while(scanf("%d%d",&n,&k),n||k)
           {
          
                  for(i=0;i<n;i++)
                         scanf("%lf",&a[i]);
                  left=0;
                  right=100000;
                  while(right-left>1e-8)            //推断是否符合要求
                  {
                         mid=(left+right)/2;
                         if(find(mid))          //电缆不是最长
                                left=mid;
                         else         //电缆段数不够
                                right=mid;
                  }
                  right=(int)(right*100)/100.0;         //right。mid,left都符合要求。可是right是最大的,更符合要求。
                  printf("%.2lf
    ",right);          //并且不能四舍五入。防止电缆不够
           }
           return 0;
    }


  • 相关阅读:
    干嘛
    有一种姑娘 你只想温柔以待
    衡阳拜佛
    浅谈程序员的英语学习【转】
    linux下用C编写的基于smtp的邮件发送程序【转】
    清空消息队列的缓存buffer
    不要对C++类对象或struct对象做memset操作
    xml解析编辑网站
    gdb调试
    喂狗机制 Software Dog
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8391027.html
Copyright © 2011-2022 走看看