牛客网暑期ACM多校训练营(第四场)Maximum Mode

链接: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;
}

猜你喜欢

转载自blog.csdn.net/gtuif/article/details/81706878