Codeforces Round #773 (Div.1) A.Great Sequence

一道很喜欢很有趣的题目

这道题目用 m a p map map来做会非常便利并且好实现!我愿将其称之为 G r e a t   P r o b l e m   ! Great\ Problem\ ! Great Problem !

来自 c f   D i v . 1 cf\ Div.1 cf Div.1

G r e a t   S e q u e n c e Great\ Sequence Great Sequence

思路:

根据题意,我们可以想到 运用 m a p map map会很容易实现将输入序列按从大到小排序且可以获得每个输入序列元素的数量,这正是这道题目的关键!

通过 m a p map map以上的功能,我们来分析这题的解题思路:

我们遍历 m a p map map ,每次将最小的元素(也就是 m a p map map中当前最前面的元素)乘 x x x,此处命名为 n u m num num,,并查找 m a p map map中是否存在 n u m num num,并且如果 m a p map map中没有这个元素,那么说明我们需要添加额外的数来满足题意,那么我们定义一个计数器 c n t cnt cnt来统计需要额外增加多少数,并且此处将 c n t + cnt+ cnt+此时的元素的数量,如果 m a p map map中存了 n u m num num这个数据,那么我们需要比较二者的数量,如果 n u m num num的数量多,那么将 n u m num num的数量 − - 当前元素的数量,也就是得到在与当前元素匹配完 n u m num num还剩几个。如果当前元素的数量比 n u m num num的数量多,那么说明 m a p map map中的元素数量不够匹配,那么我们也需要添加额外的数来满足题意,那么此时我们将 c n t + cnt+ cnt+ 需要增加的额外的数量,同时! e r a s e ( n u m ) erase(num) erase(num) !否则,下一轮遍历仍然会遍历到 m a p map map,即使 第二键值为 0 0 0!所以 ,只要 元素个数不为 0 0 0,我们就对其遍历查找。

#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int t,n,x,a; cin >> t;
    map<int,int>mp;
    while(t--){
        mp.clear();
        cin >> n >> x;
        int num=0,cnt=0;
        for(int i=0;i<n;i++) cin >> a,mp[a]++;
        for(auto i : mp){          
            num=i.first*x;
            if(mp.count(num)){
                if(i.second>=mp[num]) cnt+=i.second-mp[num],mp.erase(num);
                else mp[num]-=i.second;
            }
            else cnt+=i.second;
        }
        cout << cnt << endl;
    }    
    return 0;
}

注意: 这题在乘法那一步会爆 i n t int int!

d e f i n e   i n t   l o n g   l o n g define\ int\ long\ long define int long long还是很有必要的!

Debug过程中发现的问题:

  • 如果 我们定义的迭代器不加 & \& & 那么我们无法按改变当前的第二键值,相反加了就可以~

  • 还有一个点在上面提过了,只要一个元素存在了 m a p map map中,不管它的 s e c o n d second second是否为 0 0 0,只要不 e r a s e erase erase它,在后续遍历中依然会遍历到它!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值