PAT甲级——1129 Recommendation System——分数 25

题目


16分的解法

点击查看代码
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

map<int,int> m;

vector<pair<int,int> > find123(map<int,int> m){
    vector<int> key(3,0);
    vector<int> value(3,0);
    vector<pair<int,int> >top3;
    for(auto it = m.begin();it !=m.end();it++){
        if(it->second>value[0]){
            value[0]=it->second;
            key[0] = it->first;
        }
    }
    for(auto it = m.begin();it !=m.end();it++){
        if(it->second>value[1] && it->first!=key[0]){
            value[1]=it->second;
            key[1] = it->first;
        }
    }
    for(auto it = m.begin();it !=m.end();it++){
        if(it->second>value[2] && it->first!=key[0] && it->first!=key[1]){
            value[2]=it->second;
            key[2] = it->first;
        }
    }
    for(int i =0,j=0,k=0;i<3;i++,j++,k++){
        top3.push_back({key[j],value[k]});
    }
    return top3;
}
bool cmp(const pair<int,int>& p1,const pair<int,int>& p2){
    if(p1.second != p2.second) return p1.second>p2.second;
    else 
        return p1.first < p2.first;
}

int main(){
    int n,k; scanf("%d %d",&n,&k);
    vector<pair<int,int> > v;

    for(int i =0;i<n;i++){
        int q; scanf("%d",&q);
        if(i>0){
            printf("%d:",q);
            vector<pair<int,int> > top3 = find123(m);
            sort(top3.begin(),top3.end(),cmp);
            for(int j=0;j<k;j++){
                if(top3[j].first==0) continue;
                printf(" %d",top3[j].first);
            }
            printf("\n");
        }
        m[q]++;
    }
    return 0;
}

满分解法

点击查看代码
#include <iostream>
#include <unordered_map>
#include <set>
using namespace std;

// 自定义排序规则
struct cmp {
    bool operator()(const pair<int, int>& a, const pair<int, int>& b) const {
        if (a.second != b.second) return a.second > b.second;  // 访问次数降序
        return a.first < b.first;  // 访问次数相同时,索引升序
    }
};

int main() {
    int n, k;
    scanf("%d %d", &n, &k);

    unordered_map<int, int> freq;  // 记录每个商品的访问次数
    set<pair<int, int>, cmp> topK; // 维护前 K 大的元素

    for (int i = 0; i < n; i++) {
        int q;
        scanf("%d", &q);

        // 输出推荐(从第二次访问开始)
        if (i > 0) {
            printf("%d:", q);
            int count = 0;
            for (const auto& p : topK) {
                printf(" %d", p.first);
                if (++count == k) break;  // 仅输出前 K 个
            }
            printf("\n");
        }

        // 先从 set 中移除当前旧的元素(如果存在)
        auto it = topK.find({q, freq[q]});
        if (it != topK.end()) topK.erase(it);

        // 更新访问次数
        freq[q]++;

        // 再插入更新后的元素
        topK.insert({q, freq[q]});
    }

    return 0;
}

拓展

1.除了 set 之外,mappriority_queue 也可以使用 自定义 cmp结构体(也叫仿函数) 规则来实现插入时自动排序。

vector只能用 sort(vector.begin(), vector.end(), cmp) 手动指定排序规则

  1. 仿函数(Functor)

仿函数(Functor)是 C++ 里的一个特性,它指的是“行为像函数的对象”。仿函数本质上是一个重载了 operator() 的类或结构体,这样它的实例可以像普通函数一样被调用

#include <iostream>
using namespace std;

// 定义一个仿函数
struct Add {
    int operator()(int a, int b) const {
        return a + b;
    }
};

int main() {
    Add add;  // 创建 Add 结构体的对象
    cout << add(3, 5) << endl;  // 调用 add 实例,就像调用函数一样
    return 0;
}

// 输出:8

posted on 2025-03-17 10:32  LEESOL-cn  阅读(9)  评论(0)    收藏  举报

导航