Flowers(priority_queue优先队列)(pta)

浪子不回头ぞ 提交于 2020-03-08 00:03:22

Recently Jack becomes much more romantic. He would like to prepare several bunches of flowers.

Each bunch of flowers must have exactly M flowers. As Jack does not want to be boring, he hopes that flowers in the same bunch are all different species. Now there are N species of flowers in the flower shop, and the number of the i-th species of flower is a​i​​. Now Jack would like to know how many bunches of flowers he can prepare at most.

(Flowers are used to propose.)

Input

The first line contains an integer T (1≤T≤10) --- the number of test cases.

In the first line of each test case, there are two integers N, M (1≤N,M≤300000) --- the number of flowers' species and the number of flowers in a bunch.

In the second line of each test case, there are N integers --- the i-th integer indicates a​i​​ (1≤a​i​​≤10​9​​), the number of i-th species' flowers.

Output

For each test case, output one integer in one line --- the answer of the corresponding test case.

Sample Input

1
5 3
1 1 1 2 1

Sample Output

2

 

题意:

花店有n种花,每种花有ai朵。

一个人要以束为单位买花,每束花有m朵,并且是m种不同类型的。

问他最多能买多少束。

 

思路:

来自身边大神的引导

优先队列是最合适此题的数据结构,可以出队、进队,还能自动排序(升序)。

每次取出剩余数量最多的m种花,把这m种花都减去其中最少的那种花的数量,也就是说又凑出了这么多束,答案进行累加。如果减完之后还有剩余,则重新加入队列。

需要注意的一点是,等剩余的花的种类不多的时候,这种方法将不再是最佳。那么就需要一束一束的减,相当于每凑出一束,又进行排序。

 

爱吃代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
priority_queue<int >q;
int s[300010];
int main()
{
    int t,i,n,m,a;
    long long ans;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        while(!q.empty())
            q.pop();
        for(i=0;i<n;i++)
        {
            scanf("%d",&a);
            q.push(a);
        }
        ans=0;
        while(!q.empty())
        {
            if(q.size()<=2*m)
                break;
            for(i=0;i<m;i++)
            {
                s[i]=q.top();
                q.pop();
            }
            for(i=0;i<m-1;i++)
            {
                if(s[i]-s[m-1]>0)
                    q.push(s[i]-s[m-1]);
                else
                    break;
            }
            ans+=s[m-1];
        }
        while(!q.empty())
        {
            if(q.size()<m)
                break;
            for(i=0;i<m;i++)
            {
                s[i]=q.top();
                q.pop();
            }
            for(i=0;i<m;i++)
            {
                if(s[i]-1>0)
                    q.push(s[i]-1);
                else
                    break;
            }
            ans++;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!