小明和完美序列——map

本文介绍了一种算法,通过C++中的map统计整数数组中每个数字的出现次数,对于出现次数大于数字本身的,只保留其本身数量,从而优化问题。当出现次数小于数字时,全部删除。适用于数字范围最大为10^9的情况。
摘要由CSDN通过智能技术生成

由完美序列的定义可以知道,序列中每个数字的个数,要么是等于它本身,要么就是一个没有。

如果一个数字出现的次数比它本身大,我们就选择删掉多出的,

这样肯定比完全删除是更优的,只有在当一个数字出现的次数小于它本身的时候,这种情况,我们不得不选择全部删除。

所以解决这个问题,只要统计每个数字出现的次数就可以了。由于数字的范围最大有 10^9 ,所以我们用一个 map 统计

 

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;//由于数字的范围最大有 10^9

signed main()
{
    int n; cin >> n;
    vector<int> a(n + 1);//定义vector数组, 容量为n+1
    map<int, int> cnt;
    //输入
    for(int i = 1; i <= n; i ++) {
        cin >> a[i];
        cnt[a[i]] ++;
    }
    int ans = 0;
    for(auto [x, y] : cnt)
   {
      //出现的次数>数字本身,删除掉多余的,直到等于数字本身为止.
        if(y > x) ans += y - x;//算出要删除的次数,删除y-x次
      else if(y < x) ans += y;//如果比数字小,则全删除,删除y次
    }
    cout << ans;
}

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值