一千题,No.0003(Card Exchange)

描述

You have a hand of n cards, where each card has a number written on it, and a fixed integer k. You can perform the following operation any number of times:

  • Choose any k cards from your hand that all have the same number.
  • Exchange these cards for k−1 cards, each of which can have any number you choose (including the number written on the cards you just exchanged).

Here is one possible sequence of operations for the first example case, which has k=3:

What is the minimum number of cards you can have in your hand at the end of this process?

输入描述

The first line of the input contains a single integer t (1≤t≤500) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers n and k (1≤n≤100, 2≤k≤100) — the number of cards you have, and the number of cards you exchange during each operation, respectively.

The next line of each test case contains n integers c1​,c2​,…cn​ (1≤ci​≤100) — the numbers written on your cards.

输出描述

For each test case, output a single integer — the minimum number of cards you can have left in your hand after any number of operations.

用例输入 1 

7
5 3
4 1 1 4 4
1 10
7
7 2
4 2 1 100 5 2 3
10 4
1 1 1 1 1 1 1 1 1 1
5 2
3 8 1 48 7
6 2
10 20 30 10 20 40
6 3
10 20 30 10 20 40

用例输出 1 

2
1
1
3
5
1
6

翻译:

描述

你有 n张牌,每张牌上都写着一个数字,以及一个固定的整数 k。您可以多次执行以下操作:

从你的手牌中选择任何具有相同数字的 k张卡。

将这些卡换成 k−1张卡,每张卡都可以有您选择的任何号码(包括您刚刚交换的卡上写的号码)。

在此过程结束时,您手上至少可以拥有多少张牌?(多组样例)

输入描述

输入的第一行包含单个整数t (1≤≤500) — 测试用例的数量。测试用例的描述如下。

每个测试用例的第一行包含两个整数nk (1≤n≤100,2≤k≤100) — 您拥有的卡数量,以及您在每次操作期间交换的卡数量。

每个测试用例的下一行包含n整数c1​,c2​,...cn​ (1≤c​≤100) — 写在卡片上的数字。

输出描述

对于每个测试用例,输出一个整数 — 在任意数量的操作后,您手中可以剩余的最小卡片数。

解题思路

该题大意为:将卡片不限次数处理后得出的最小卡组数量,因为每次处理后卡片数量-1。

所以该题可以理解为:当处理条件符合时对卡组进行处理,并且对卡组处理时应向符合条件的方向处理,否则输出卡组数量。

c++代码如下:

#include <iostream>
#include <map>

using namespace std;

int main()
{
    int n;
    cin >> n;
    while(n--)
    {
        int x,y;
        cin >> x >> y;
        multimap<int,int> m;
        while(x--)
        {
            //插入数据
            int num;
            cin >> num;
            if(m.find(num) == m.end())
            {
                m.insert({num,1});
            }
            else
            {
                auto t = m.find(num);
                ++t->second;
            }
        }

        //使卡牌数量自动排序
        multimap<int,int> m1;
        for(auto &elem:m)
        {
            m1.insert({elem.second,elem.first});
        }

        //处理卡牌
        while(m1.rbegin()->first >= y && m1.size() > 1)
        {
            //要变换的卡牌,为助于理解赋了初值
            int num = m1.rbegin()->first;
            int card = m1.rbegin()->second;
            //转换卡牌
            --num;
            num += (++m1.rbegin())->first;
            card = (++m1.rbegin())->second;
            //删除原卡牌
            m1.erase(--m1.end());//倒数第一个
            m1.erase(--m1.end());//倒数第二个
            //插入卡牌
            m1.insert({num,card});
        }

        //输出最小数量
        if(m1.rbegin()->first >= y && m1.size() == 1)
        {
            cout << y-1 << endl;
        }
        else
        {
            int res = 0;
            for(auto &elem : m1)
            {
                res += elem.first;
            }
            cout << res << endl;
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值