• 《信息学奥赛一本通》分治算法 找数 例题


    【描述】

    给一个长度为n的单调递增的正整数序列,即序列中每一个数都比前一个数大。
    有m个询问,每次询问一个x,问序列中最后一个小于等于x的数是什么?

    【输入】

    第一行两个整数n,m。
    接下来一行n个数,表示这个序列。
    接下来m行每行一个数,表示一个询问。

    【输出】

    输出共m行,表示序列中最后一个小于等于x的数是什么。
    假如没有,则输出-1.

    【样例输入】

    5 3
    1 2 3 4 6
    5
    1
    3

    【样例输出】

    4
    1
    3

    【分析】

    用left表示序列的左边界,用right表示序列的右边界,[left,right]组成序列。
    一开始left=1,right=n。序列已经按照升序排好,保证了二分的有序性。
    二分的步骤:
    1.去序列区间的中间值mid=(left+right)/2;
    2.判断mid与x的关系,如果a[mid]>x,所以区间[mid,right]直接排除,修改right=mid-1;
    如果a[mid]<x,所以区间[left,mid]直接排除,修改right=mid+1;
    3.重复执行二分操作知道left>right。
    最终循环结束时一定是left=right+1,所以最后的结果为right指向的值。

    #include <iostream>
    using namespace std;
    int main ()
    {
     int n,m,a[10000];
     cin>>n>>m;
     for(int i=1;i<=n;i++)
     {
      cin>>a[i];
     }
     a[0]=-1;
     for(int i=1;i<=m;i++)
     {
      int x;
      cin>>x;
      int left=1,right=n,mid;
      while(left<=right)
      {
       mid=(left+right)/2;
       if(a[mid]<=x)
       {
        left=mid+1;
       }
       else
       {
        right=mid-1;
       }
      }
      cout<<a[right]<<endl;
     }
     return 0;
    }
    
  • 相关阅读:
    透过书本了解HTML5
    Seam性能讨论
    Maven依赖管理
    Tapestry
    为HTML5的未来制定学习计划
    后缀数组
    HDU 1042(大数)
    教你理解复杂的C/C++声明
    编程修养
    平衡二叉树
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12339602.html
Copyright © 2020-2023  润新知