【牛客小白月赛117】D题——众数刷题启示

牛客小白月赛117 D题
D题求众数可以用排序去解决,排序要两个要求:1.按出现次数从大到小排序(示例1);2.如果出现次数相同,按数字从大到小排序(示例2)。
我参考了一个大神的AC代码,代码用STL的sort做排序。其中的cmp函数我学到了东西:

变量说明: 
a,b:输入的数字
num[a]:数字a出现的次数
num[b]:数字b出现的次数

若num[a]==num[b]则比较a和b谁大,return a>b; 否则return num[a]>num[b]。

bool cmp(int a,int b){
	if(num[a]==num[b]) return a>b;
	else return num[a]>num[b];
} 

除了排序外,我还看了一下解题思路:
这道题的数字存在数组v中,出现次数存在num数组中,用数组b(类似于集合),存储出现过的次数。在输入数据后,我们用cmp函数对b数组元素按照从大到小排序。
题目操作中v[i],v[j],v[j]-1,v[i]+1这四项的出现的次数会影响最终结果。我们用双重循环枚举其中的i,j且要满足i!=j。拿到满足条件的i和j,我们就去更新一下num数组对应的下标,在这里我们考虑b数组的前4项,以及次数增加的i+1和j-1,把它们加进数组w中,我们之后对w数组按照cmp函数进行排序。排序后,第一位的元素是这组数的众数。
为什么是前四项?
因为题目操作主要涉及v[i],v[j],v[j]-1,v[i]+1,假设前四项就是这四项,那通过操作有可能排在2,3,4位的项会来到第一。
完整AC代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int num[N];
bool cmp(int a,int b){
	if(num[a]==num[b]) return a>b;
	else return num[a]>num[b];
} 
void work(){
	int n;
	cin>>n;
	vector<int> v(n);
	vector<int> b;
	for(int i=0;i<n;i++){
		cin>>v[i];
		num[v[i]]++;
		if(num[v[i]]==1){
			b.push_back(v[i]);
		}
	}
	sort(b.begin(),b.end(),cmp);
	set<int> ans;
	int m=v.size();
	for(int i=0;i<n;i++){
		for(int j=0;j<n;j++){
			if(i==j) continue;
			int x=v[i],y=v[j];
			num[x]--,num[y]--;
			num[x+1]++,num[y-1]++;
			vector<int> w;
			for(int k=0;k<min(m,3);k++) w.push_back(b[k]);
			w.push_back(x+1),w.push_back(y-1);
			sort(w.begin(),w.end(),cmp);
			ans.insert(w[0]);
			num[x]++,num[y]++;
			num[x+1]--,num[y-1]--;
		}
	}
	set<int>::iterator it=ans.begin();
	for(it=ans.begin();it!=ans.end();it++) cout<<*it<<" ";
}
int main(){
	work();
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值