牛客网暑期ACM多校训练营(第四场)G Maximum Mode 题解 思维题

链接:https://www.nowcoder.com/acm/contest/142/G
来源:牛客网
 

Maximum Mode

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 131072K,其他语言262144K
64bit IO Format: %lld

题目描述

The mode of an integer sequence is the value that appears most often. Chiaki has n integers a1,a2,...,an. She woud like to delete exactly m of them such that: the rest integers have only one mode and the mode is maximum.

输入描述:

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains two integers n and m (1 ≤ n ≤ 105, 0 ≤ m < n) -- the length of the sequence and the number of integers to delete.
The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) denoting the sequence.
It is guaranteed that the sum of all n does not exceed 106.

输出描述:

For each test case, output an integer denoting the only maximum mode, or -1 if Chiaki cannot achieve it.

示例1

输入

复制

5
5 0
2 2 3 3 4
5 1
2 2 3 3 4
5 2
2 2 3 3 4
5 3
2 2 3 3 4
5 4
2 2 3 3 4

输出

复制

-1
3
3
3
4

题意:n个整数a1,,...,an。 想要删除其中的m个,输出相同个数最多的数字(如果个数相同则不行,并使这个数字尽可能大
输入描述:
有多个测试用例。T,
n和m(1≤n≤105,0≤m<n) - 序列的长度和要删除的整数。
输出描述:
对于每个测试用例,输出一个表示唯一最大模式的整数,如果无法实现,则输出-1。

思路:对n个数从小到大进行排序 每个数一共有多少种数 按数量从小到大排序

         最后按照数量的从多到少 用m减去 记录过程中可构成的最大值 输出;

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int val;///数值
    int num;///数量
    int sum;///要使其为众数,需要减掉的数量
}b[100005];
bool cmp(node a,node b)
{
    return a.num<b.num;
}
int ncase,n,k;
int a[100005];
int main()
{
    while(~scanf("%d",&ncase))
    {
        while(ncase--){
            scanf("%d %d",&n,&k);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            sort(a+1,a+n+1);///对n个数从小到大进行排序 每个数一共有多少种数 按数量从小到大排序
            int tot=0;///一共有多少种数
            int cnt=0;///数量
            for(int i=1;i<n;i++){
                if(a[i]!=a[i+1]){
                    b[++tot].val=a[i];
                    b[tot].num=cnt+1;//数量的前缀和
                    cnt=0;
                }
                else cnt++;//前缀和
            }
            b[++tot].val=a[n];
            b[tot].num=cnt+1;
            sort(b+1,b+tot+1,cmp);///按数量从小到大排序
            b[1].sum=n-b[1].num-(tot-1)*(b[1].num-1);//总数n-当前a[i]值的个数(留下 不需要删)-其余的种数*其余的个数
            int sum1=b[1].num;///储存i之前不需要删除的数量
            cnt=1;///储存i之前不需要删除的数有几个
            for(int i=2;i<=tot;i++){
                if(b[i].num==b[i-1].num){///如果数量与前一个相等,那么要删除的也相等
                    b[i].sum=b[i-1].sum;
                    sum1+=b[i].num;
                    cnt++;
                }
                else{
                    sum1+=b[i].num;
                    b[i].sum=n-sum1-(tot-cnt-1)*(b[i].num-1);
                    cnt++;
                }
            }
            int ans=-1;
            for(int i=1;i<=tot;i++){///遍历找到最优解
                if(b[i].sum<=k)
                    ans=max(b[i].val,ans);
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41668093/article/details/81272594
今日推荐