Codeforces ~ 990B ~ Micro-World (排序+模拟)

本文探讨了一道关于细菌存活数量的算法题目,给出了两种解法。一种是通过排序和vector模拟来解决,另一种则采用桶排序及前缀和的方法进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

***题意:***有N个细菌,当且仅当ai>aj且ai≤aj+ka_i>a_j且a_i≤a_j+kai>ajaiaj+k细菌iii可以吃jjj,问最少可能剩下多少细菌?

解法一: 从小到大排个序,每次新加进来一个的时候把,它能吃的的都吃掉,用vector模拟即可。

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+5;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int n, k, a[MAXN];
int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++) scanf("%d", &a[i]);
    sort(a, a+n);
    vector<int> S;
    for (int i = 0; i < n; i++)
    {
        while (!S.empty() && a[i] > S.back() && a[i] <= S.back()+k)
            S.pop_back();
        S.push_back(a[i]);
    }
    printf("%d\n", S.size());
    return 0;
}
/*
7 1
101 53 42 102 101 55 54
*/

解法二: 比赛的时候想到的一种写法,挺麻烦的。。。桶排序,存储一下这些点,然后再求个前缀和。然后每个点只能吃掉它前面的k个点,但是有些点可能已经被吃过了,我们要避免重复吃,所以我们用一个变量pos维护前面已经吃到了哪个位置。对于第iii个位置,如果有细菌的话,那么他就可以吃掉[i−k−1,i−1][i-k-1,i-1][ik1,i1]区间内的细菌,考虑上重复吃的情况,那么就是[max(i−k−1,pos),i−1][max(i-k-1,pos),i-1][max(ik1,pos),i1],统计被吃掉了多少就OK了

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6+5;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int n, k, a[MAXN], sum[MAXN];
int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 0; i < n; i++)
    {
        int t; scanf("%d", &t);
        a[t]++;
    }
    for (int i = 1; i <= 1e6; i++) sum[i] = sum[i-1]+a[i];
    int pos = 0, ans = n;
    for (int i = 1; i <= 1e6; i++)
    {
        if (a[i])
        {
            ans -= sum[i-1] - sum[max(pos-1, i-k-1)];
            pos = i;
        }
    }
    printf("%d\n", ans);
    return 0;
}
/*
7 1
101 53 42 102 101 55 54
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值