链接:https://www.nowcoder.com/acm/contest/142/G
来源:牛客网
时间限制: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个数的序列,要求去掉m个数,使序列出现一个最大的惟一的众数;若不存在就输出-1;
思路:我写的很麻烦,记录每个数出现的次数,再记录每个次数出现的次数;先求出每个数的次数,然后选出相同次数中最大的数(比如2和3都出现了3次,那么出现3次的数为3),然后遍历符合条件的数,这样就得到了答案;判断条件的话就是先统计每个次数相同的个数,然后维护前缀和,算出要使当前数成为最大的众数序列要减去的个数,与m比较;差不多就这样;
下面附上我的代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<map>
#include<set>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<stack>
#include<string>
#define LL long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define lson o<<1
#define rson o<<1|1
using namespace std;
const int maxn = 1e5 + 10;
set<int> s;
set<int> s1;
struct node {
int val;
int mx;
} a[maxn];
struct node1{
int vall;
int mxx;
int num;
}d[maxn], c[maxn];
bool cmp1(node1 c, node1 d)
{
return c.vall > d.vall;
}
bool cmp2(node1 x, node1 y)
{
return x.mxx > y.mxx;
}
map<int, int> b;
map<int, int> b1;
map<int, int> p;
int main()
{
int n, m, k;
scanf("%d", &k);
while (k--)
{
s.clear();
b.clear();
p.clear();
b1.clear();
s1.clear();
scanf("%d %d", &n, &m);
int x;
for (int i = 0; i < n; i++)
{
scanf("%d", &x);
b[x]++;//次数
s.insert(x);
}
set<int>::iterator it;
int t = 0;
for(it = s.begin(); it != s.end(); it++)
{
a[t].mx = b[*it];
a[t++].val = *it;
}
for(int i = 0; i < t; i++)
{
p[a[i].mx]++;//相同次数的个数
b1[a[i].mx] = max(b1[a[i].mx], a[i].val);//相同次数的最大值
s1.insert(a[i].mx);//去重次数
}
set<int>::iterator iter;
int v = 0;
for(iter = s1.begin(); iter != s1.end(); iter++)
{
d[v].mxx = *iter;
d[v].vall = b1[*iter];
d[v++].num = p[*iter];
}
sort(d, d + v, cmp2);
int r = 0;
int sum[maxn];
int sum1[maxn];
memset(sum, 0, sizeof(sum));
memset(sum1, 0, sizeof(sum1));
sum[0] = d[0].mxx * d[0].num;
sum1[0] = d[0].mxx;
for(int i = 1; i < v; i++)
sum[i] = sum[i - 1] + d[i].mxx * d[i].num;
for(int i = 1; i < v; i++)
sum1[i] = sum1[i - 1] + d[v - i].num;
for (int i = 0; i < v; i++)
{
if (m >= (sum[v - 1] - sum[i] - (sum1[v - 1] - sum1[i]) * (d[i].mxx - 1) + d[i].num - 1))
break;
}
sort(c, c + r, cmp1);
if (!r)
puts("-1");
else
printf("%d\n", c[0].vall);
}
return 0;
}