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


    【描述】

    给一个长度为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;
    }
    
  • 相关阅读:
    C++ 子类调用基类构造函数的简单示例
    无锁编程原子操作 概念记录
    C++ 随手bug 小计
    vector size函数也有大大的坑
    vb.net Try 错误导致 For Each 循环中断
    mysql5.7执行sql语句成功,但是报错Err:1055
    python生成EXE可执行文件的方法
    mysql5.7修改my.ini的默认字符集后,无法重启服务
    日历中常用的功能
    Maven的配置
  • 原文地址:https://www.cnblogs.com/AlexKing007/p/12339603.html
Copyright © 2020-2023  润新知