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
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<queue> 5 #include<set> 6 using namespace std; 7 typedef struct NODE{ 8 int id; 9 int cnt; 10 }info; 11 bool operator <(const info &a, const info &b){ 12 if(a.cnt == b.cnt) 13 return a.id < b.id; 14 else return a.cnt > b.cnt; 15 } 16 set<info> st; 17 int hashTB[50001] = {0}; 18 int main(){ 19 int N, K, qu; 20 scanf("%d%d%d", &N, &K, &qu); 21 info temp = {qu, 1}; 22 st.insert(temp); 23 hashTB[qu]++; 24 for(int i = 1; i < N; i++){ 25 scanf("%d", &qu); 26 printf("%d:", qu); 27 set<info>::iterator itp; 28 int prt; 29 for( prt = 0, itp = st.begin(); prt < K && itp != st.end(); prt++, itp++){ 30 printf(" %d", itp->id); 31 } 32 printf(" "); 33 info nd = {qu, hashTB[qu]}; 34 set<info>::iterator it = st.find(nd); 35 if(it != st.end()){ 36 st.erase(it); 37 } 38 nd.cnt = ++hashTB[qu]; 39 st.insert(nd); 40 } 41 cin >> N; 42 return 0; 43 }
总结:
1、题意:动态统计次数。每当用户购买一个东西时,从他购买该东西之前的购买历史中统计出高买次数最多的前K个产品,并推荐给他。
2、N很大,所以每次都排序肯定超时。 由于set可以保证内部有序,所以使用set来排序,用hash表来统计出现频率。每次新购一个物品,先去set中查找,如果存在则删除再重新插入更新后的,如果不存在则直接插入。
3、set重载小于号,在struct外:
bool operator <(const info &a, const info &b){ if(a.cnt == b.cnt) return a.id < b.id; else return a.cnt > b.cnt; }
4、set使用find函数查找 struct 类型变量时,由于已经重载了小于号,所以set会利用小于号来判断不等于。所以可以正常传入一个struct变量 a 并在find函数中查找成员变量都和a相等的变量。
5、给分最多的几个测试点好像用时在2ms左右,所以到时候实在想不到就暴力破解。