PAT A1129 Recommendation System (25) [set的应⽤,运算符重载]

题目

Recommendation system predicts the preference that a user would give to an item. Now you are asked to program a very simple recommendation system that rates the user’s preference by the number of times that an item has been accessed by this user.
Input Specification:
Each input file contains one test case. For each test case, the first line contains two positive integers: N (<= 50000), the total number of queries, and K (<= 10), the maximum number of recommendations the system must show to the user. Then given in the second line are the indices of items that the user is accessing — for the sake of simplicity, all the items are indexed from 1 to N. All the numbers in a line are separated by a space.
Output Specification:
For each case, process the queries one by one. Output the recommendations for each query in a line in the format:
query: rec[1] rec[2] … rec[K]
where query is the item that the user is accessing, and rec[i] (i = 1, … K) is the i-th item that the system recommends to the user. The first K items that have been accessed most frequently are supposed to be recommended in non-increasing order of their frequencies. If there is a tie, the items will be ordered by their indices in increasing order.
Note: there is no output for the first item since it is impossible to give any recommendation at the time. It is guaranteed to have the output for at least one query.
Sample Input:
12 3
3 5 7 5 5 3 2 1 8 3 8 12
Sample Output:
5: 3
7: 3 5
5: 3 5 7
5: 5 3 7
3: 5 3 7
2: 5 3 7
1: 5 3 2
8: 5 3 1
3: 5 3 1
8: 3 5 1
12: 3 5 8

题目分析

输入一系列数字,除第一次输入外,后面每次查询,需输出之前序列(要求无重复输出,依据出现频率高到低排序,如果出现频率相同,按照数字从小到大排序)

解题思路

思路 01 set重载运算符

  1. 使用set保存之前出现的所有数字,并依照题意自定义set的排序规则
  2. 每次查询,需要判断之前是否出现过,若出现过,需要删除再插入以触发set排序器
  3. 注:题目已知第一次查询无需打印

知识点

set 遍历

int cnt = 0;
for(auto it=rcs.begin(); cnt<k&&it!=rcs.end(); it++,cnt++)
	printf(" %d",it->num);

set 查询和删除

auto it = rcs.find({a,book[a]}); //是否以前已经出现过 
if(it!=rcs.end()) rcs.erase(it); //删除再插入,触发set自定义排序 
rcs.insert({a,++book[a]});

set 自定义比较器--通过重载运算符实现

struct node {
	int num;
	int ts;
	// 重载<运算符,实现set自定义排序
	bool operator < (const node & nd) const {
		return nd.ts!=ts?ts>nd.ts:num<nd.num;
	}
};

Code

#include <iostream>
#include <set>
using namespace std;
const int maxn=50010;
struct node {
	int num;
	int ts;
	// 重载<运算符,实现set自定义排序
	bool operator < (const node & nd) const {
		return nd.ts!=ts?ts>nd.ts:num<nd.num;
	}
};
set<node> rcs; // 记录容器--记录排序后的查询结果 
int book[maxn];// 记录重复次数--book[i]=t,第i个元素已重复出现t次 
int main(int argc,char * argv[]) {
	int n,k,a;
	scanf("%d %d",&n,&k);
	for(int i=0; i<n; i++) {
		scanf("%d",&a);
		if(i!=0) { //第一个查询不打印,之后的查询,打印结果 
			printf("%d:",a);
			int cnt = 0;
			for(auto it=rcs.begin(); cnt<k&&it!=rcs.end(); it++,cnt++)
				printf(" %d",it->num);
			printf("\n");
		}
		auto it = rcs.find({a,book[a]}); //是否以前已经出现过 
		if(it!=rcs.end()) rcs.erase(it); //删除再插入,触发set自定义排序 
		rcs.insert({a,++book[a]});
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/houzm/p/12897126.html