zoukankan      html  css  js  c++  java
  • 二分

    题目链接

    http://bailian.openjudge.cn/practice/4134/

    分析一波

    题目要在一个比较大的非降序列表中,寻找最接近给定值a的列表中元素,如果使用顺序查找,很可能就超时了,在这里,考虑使用二分查找。
    二分查找一定要求待查找序列有序,在二分查找中,判定查找结束的条件是 low > high,因为这里low == high 也是允许的,如果没有找到一个给定元素,那么这个元素一定是夹在 List[high] 和 List[low]之间。
    二分作为一种算法思想,其应用范围不仅限于查找,也可进行枚举,比如我们熟悉的用二分法寻找方程的根,需要枚举一个范围内的所有点,使用二分法就可以每次将这个范围减半,从而加快根的寻找。但是使用二分需要待查找数据满足某种"单调性",在二分查找中,需要带查找序列有续,所以能够在待查元素与中间元素比较后,能够将一半的元素排除掉;在求方程根的问题中,需要函数在一段区间内保持单调,所以在中点的函数值大于0的时候能排除一半的区间。
    其他二分的应用场景都有类似单调的限制。

    解题代码

    #include <cstdio>
    #include <cstring>
    #define MAX 100010
    
    int List[MAX];
    int n;
    
    int main(){
        scanf("%d", &n);
        memset(List, 0, sizeof(List));
        for(int i = 0; i < n; i++){
            scanf("%d", List + i);
        }
        
        int m;
        scanf("%d", &m);
        while(m--){
            int a;
            scanf("%d", &a);
            int low = 0, high = n - 1, mid = (low + high)/2;
            while(low <= high){
                mid = (low + high) / 2;
                if(List[mid] > a) high = mid - 1;
                else if(List[mid] < a) low = mid + 1;
                else break;
            }
            if(low <= high)
                printf("%d
    ", List[mid]);
            else{
                if(high < 0)
                    printf("%d
    ", List[0]);
                else if(low >= n)
                    printf("%d
    ", List[n - 1]);
                else if(List[low] - a >= a - List[high])
                    printf("%d
    ", List[high]);
                else if(List[low] - a < a - List[high])
                    printf("%d
    ", List[low]);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    洛谷 P1972 [SDOI2009]HH的项链
    洛谷P1494 BZOJ2038【国家集训队】小Z的袜子
    联合体以及如何调出内存窗口
    利用C语言结构体模拟一个简单的JavaBean
    结构体赋值
    C语言结构体赋值2
    结构体所占内存大小
    C语言结构体的引入
    堆的申请和释放2
    堆的申请和释放
  • 原文地址:https://www.cnblogs.com/zhangyue123/p/12597367.html
Copyright © 2011-2022 走看看