• 【CF1100B】Build a Contest


    题意

    你有 $n$ 道题和一个 $k$,每一题的难度在 $1$ 和 $k$ 之间。

    每凑足了 $k$ 个不同难度的新题目,就必须举办一次比赛,包含 $1$ 至 $k$ 难度的题目各一道。

    当然,已经在举办的比赛用过的题目将作废,无法重复使用。

    如果你出了第 $i$ 题后要举办一次比赛了,那么 $f(i)=1$,否则 $f(i)=0$

    最后,请让 $i$ 从 $1$ 到 $n$ 按顺序输出所有的 $f(i)$,中间不用空格分开。

    $1 le n,k le 10^5$

    解析

    显然,我们可以求出可以举办的比赛次数,就是 $1$ 至 $k$ 中各个难度出现的题数的最小值。

    那我们可以求一个东西:我们如果要举办第 $x$ 次比赛,那么需要知道的是当前每一个难度的题目数是否不小于 $x.$

    这个东西很好求,我们只需要在线处理每一个难度题目数出现的次数。

    因为每一个数不大于 $10^5$,可以开一个桶记录出现相同难度的次数。

    我们定义数组 $cnt$ 为桶,$sum$ 记录答案,$sum_i$ 即为出第 $i$ 次比赛前已经有的题目数量。

    那么,对于第 $p$ 个数 $x$,让 $cnt_x$ 加一,$sum_{cnt_x}=p$ 即可。

    最后,让 $x$ 从 $1$ 推到 $min{cnt_i}$,用数组 $ans$ 记录答案序列,即让 $ans_{sum_x}=1$

    然后输出即可。

    参考代码

    #include <cstdio>
    #define N 100010

    int k, n, a, cnt[N], sum[N], ans[N], minn = 1e9; inline int min(int a, int b){ return a < b ? a : b; } int main(){ scanf("%d%d", &k, &n); for(int i=1; i<=n; i++){ scanf("%d", &a); sum[++cnt[a]] = i; }
    for(int i=1; i<=k; i++) minn = min(minn, cnt[i]); for(int i=1; i<=minn; i++) ans[sum[i]]++; for(int i=1; i<=n; i++) printf("%d", ans[i]); return 0; }
  • 相关阅读:
    安装minicom串口访问开发板
    《Linux运维趋势》2010-2013年全部期刊下载
    pap与chap协议
    简单linux网络驱动程序
    573. Squirrel Simulation
    576. Out of Boundary Paths
    568. Maximum Vacation Days
    leetcode contest 20
    55 Jump Game i && 45 Jump Game ii
    120. Triangle
  • 原文地址:https://www.cnblogs.com/zengpeichen/p/11520012.html
Copyright © 2020-2023  润新知