码迷,mamicode.com
首页 > 其他好文 > 详细

[AHOI2018初中组][二分查找] 分组

时间:2020-05-31 22:06:26      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:printf   block   pac   使用   define   初中   开始   names   cst   

以前没正经写过二分查找,就拿这个当作是板子吧

题面

最开始是想二分答案的,但是没有考虑到数据中重复的数值的情况,50 分 WA 了。。。
但是这题显然适合二分查找:

当我们的数据 在数组中是线性排列的,就可以使用二分查找。
需要两个辅助数组:

  • sz[] 用于记录每个分组的大小
  • g[] 用于记录当前分组后面需要的那个数值

你甚至还会发现这题有点蜘蛛纸牌那味(雾)

不多说闲话,下面是代码:

/*
二分查找:设计一个数组 g[] 表示第 i 个分组中 需要加入的数值
    sz[] 表示组大小
先排个序,然后就可满足单调递增即可二分查找
有重复数值时尽量加在最后一个位置
*/

# include <iostream>
# include <cstdio>
# include <algorithm>
# define MAXN 100000+5

using namespace std;

int a[MAXN], n, ans = 100005, sz[MAXN], g[MAXN], cntG;


int main(){
    int  l, r, mid;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    sort(a+1, a+n+1);
    g[0] = 1e9+1; // 可能会被搜到防止爆炸

    for(int i = 1; i <= n; i++){
        l = 0; r = cntG;
        while(l < r){
            mid = (l+r+1) >> 1;
            if(a[i] >= g[mid]) l = mid;
            else r = mid-1;
        }
        if(g[l] != a[i]){
            g[++cntG] = a[i]+1;
            sz[cntG] = 1;
        } // 注意这里一定是用 l ,不然如果没有进行上一步操作更新 mid 值的话会导致恐怖的 bug
        else{
            g[l] = a[i]+1;
            sz[l]++;
        }
    } // 对于每个 a[i] 寻找它的位置

    for(int i = 1; i <= cntG; i++)
        ans = min(ans, sz[i]);
    printf("%d", ans);
    return 0;
}

完结~~各位大佬可以大力吐槽QWQ

[AHOI2018初中组][二分查找] 分组

标签:printf   block   pac   使用   define   初中   开始   names   cst   

原文地址:https://www.cnblogs.com/Foggy-Forest/p/13021527.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!