A1129 Recommendation System

这个题目我感觉我想到了一个大部分人都没想到的方法,很开心。
题目要求是输入n个数,在输入第i个数的时候输出前面出现频率最大的前k个数。

这个题目一开始用sort排序,有两个点怎么写都超时,后来看了一些网上的解答,都用了set内部排序,需要重载<。
在我快要放弃的时候,再看一遍题目,发现了一个点,题目说K<=10,这个就很关键了,说明我可以用sort,但是可以大大降低sort的元素个数由于每次对一个新的a[i],都要排序,实际上做了大量无意义的排序,前一轮的结果是可以继续用的,那么在我代码里面的数组v的size小于k的时候尽管push,但是如果要放第k+1个了,sort以后把尾元素pop掉,这样一来,每轮sort需要排序的元素都不超过k+1个,大大节省了时间。
这个方法很取巧,如果k很大可能就不适用了,但是依然很开心我想到了这点。

#include <stdio.h>
#include <string.h>
#include <algorithm> 
#include <vector>
using namespace std;

vector<int> v;
const int maxn = 50010;
int a[maxn];	//存放序列
int cnt[maxn];	//记录每个元素出现次数
bool flag[maxn];//记录元素是否在v里面
bool cmp(int a,int b){	//sort的比较函数
	if(cnt[a]!=cnt[b])return cnt[a]>cnt[b];
	else return a<b;
}

int main(int argc, char const *argv[])
{
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=0;i<n;i++)scanf("%d",&a[i]);
	
	v.push_back(a[0]);//由于第一个不需要输出,先放进数组
	cnt[a[0]]++;
	flag[a[0]] = true;
	for(int i=1;i<n;i++){	
		printf("%d:",a[i]);
		for(int j=0;j<v.size()&&j<k;j++){//输出最前面的k个元素,如果不足k个就全部输出
			printf(" %d",v[j]);
		}
		printf("\n");
		
		cnt[a[i]]++;	//出现次数+1
		if(flag[a[i]]==false)v.push_back(a[i]);//如果a[i]不在v里面,就push进去
		flag[a[i]] = true;	//置为true
		sort(v.begin(),v.end(),cmp);//排序
		if(v.size()==11)v.pop_back();//k最大为10,因此到了11个就把尾元素pop,也可把11换成k+1
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43108373/article/details/84502452