• 二分模板


    P1918 保龄球

    题目描述

    DL 算缘分算得很烦闷,所以常常到体育馆去打保龄球解闷。因为他保龄球已经打了几十年了,所以技术上不成问题,于是他就想玩点新花招。

    DL 的视力真的很不错,竟然能够数清楚在他前方十米左右每个位置的瓶子的数量。他突然发现这是一个炫耀自己好视力的借口——他看清远方瓶子的个数后从某个位置发球,这样就能打倒一定数量的瓶子。

    1 OOO

    2 OOOO

    3 O

    4 OO

    如上图,每个“O”代表一个瓶子。如果 DL 想要打倒 3 个瓶子就在 1 位置发球,想要打倒 4 个瓶子就在 2 位置发球。

    现在他想要打倒 m 个瓶子。他告诉你每个位置的瓶子数,请你给他一个发球位置。

    输入输出格式

    输入格式:

    输入文件名为 bowling.in。

    第一行包含一个正整数 n,表示位置数。

    第二行包含 n 个正整数,第 i 个数。表示第 i 个位置的瓶子数,保证各个位置的瓶子数不同。

    第三行包含一个正整数 Q,表示 DL 发球的次数。

    第四行至文件末尾,每行包含一个正整数 m,表示 DL 需要打倒 m 个瓶子。

    输出格式:

    输出文件名为 bowling.out。

    共 Q 行。每行包含一个整数,第 i 行的整数表示 DL 第 i 次的发球位置。若无解,则输出 0。

    输入输出样例

    输入样例#1: 复制
    5
    1 2 4 3 5
    2
    4
    7
    
    输出样例#1: 复制
    3
    0
    

    说明

    【数据范围】

    对于 50%的数据,1 ≤ n,Q ≤ 1000,1 ≤ai,M ≤ 10^5

    对于 100%的数据,1 ≤ n,Q ≤ 100000,1 ≤ai,M ≤ 10^9

    这道题是经典的二分查找。二分查找有以下几点注意事项:

    1.while循环一定要l<=r,不然找到l+1==r的时候,mid=l,如果最后的答案是当前r这个位置的,而while循环里的条件又是l<r,则无法找到正确答案。(即会漏掉一个位置,而且这个位置多半是正确答案)

    2.mid可以写为l+(r-l)/2或(l+r)/2.但是要注意特殊情况特殊考虑。有些是需要写成(l+r+1)/2的

    3.二分查找一定是要在排序之后才能用,不然l和r无法更新

     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <cstdlib>
     6 #include <algorithm>
     7 using namespace std;
     8 struct data
     9 {
    10     int mark,x;
    11     bool operator <(const data&o)const
    12     {
    13         return x<o.x;
    14     }
    15 }a[101010];
    16 
    17 int main()
    18 {
    19     int n;
    20     scanf("%d",&n);
    21     for(int i=1;i<=n;i++)
    22     {
    23         scanf("%d",&a[i].x);
    24         a[i].mark=i;
    25     }
    26     sort(a+1,a+1+n);
    27     //for(int i=1;i<=n;i++) cout<<a[i].mark<<" "<<a[i].x<<endl;
    28     int T;
    29     scanf("%d",&T);
    30     for(int i=1;i<=T;i++)
    31     {
    32         int c;
    33         scanf("%d",&c);
    34         int l=1,r=n;
    35         bool ok=false;
    36         while(l<=r)
    37         {
    38             int mid=l+(r-l)/2;
    39             if(a[mid].x>c) r=mid-1;
    40             else if(a[mid].x<c) l=mid+1;
    41             else
    42             {
    43                 ok=1;
    44                 printf("%d
    ",a[mid].mark);
    45                 break;
    46             }
    47         }
    48         if(!ok) printf("0
    ");
    49     }
    50     system("pause");
    51     return 0;
    52 }
    P1918

    码一下模板。

  • 相关阅读:
    客户端命令行查看dubbo服务的生产者和消费者
    灰度发布
    灰度发布方法了解
    spring事务隔离级别
    小东西
    从excel表中生成批量SQL,将数据录入到数据库中
    CSV导出
    详解Java的自动装箱与拆箱(Autoboxing and unboxing)
    java多线程理解
    spring事务传播行为讲解转载
  • 原文地址:https://www.cnblogs.com/YXY-1211/p/7812855.html
Copyright © 2020-2023  润新知