天梯赛L2-005 集合相似度 (25 分)

做这道题的感觉就很玄学

之前代码一直跑不过去,然后今天就突然跑过去了

感觉自己也就优化了一点点啊

开始分析

题目的难点在于对于题目的解读上

给定两个整数集合,它们的相似度定义为:Nc/Nt×100%。
其中Nc是两个集合都有的不相等整数的个数,N​t是两个集合一共有的不相等整数的个数。
你的任务就是计算任意一对给定集合的相似度。

一开始我想的比较复杂,我以为一个集合里如果有重复数字就直接删掉(包括原数字)
经过测试后发现不对,实际上,题目的意思是

两个集合的交集除以并集,集合不含重复数字

也就是直接set_intersection()/set_union()就行了
分析结束,开始写代码

读取部分

vector<set<int>> SET; //在vector里放set,按照C++之父的说法,能用vector的地方就用就行了
for(int i = 0; i != N; ++i){//这里为了简洁省去了N和M,自己写的时候要加上
    set<int> vec;     //由于是vector里放集合,所以要初始化一个
    for(int j = 0, X; j != M, cin >> X; ++j)  vec.insert(X); //老师教的,强行压行的典范,一般不推荐,要看编译器自己的理解
    SET.push_back(vec);//存入集合
}

算法核心部分

set<int> cnt1(SET[x]), cnt2(SET[y]);//直接初始化,节省代码量
vector<int> A, B;  //对这段代码不清楚的可以查一下C++ reference里set的用法
set_intersection(cnt1.begin(), cnt1.end(), cnt2.begin(), cnt2.end(), insert_iterator<vector<int>>(A,A.begin()));//交集
set_union(cnt1.begin(), cnt1.end(), cnt2.begin(), cnt2.end(), insert_iterator<vector<int>>(B,B.begin()));//并集

输出部分

#include<iomanip> //不懂的可以查一下这个的C++ reference,会有一些不错的启发
cout << setprecision(2) << fixed << (double) A.size() / B.size() * 100 << '%';  

完整代码

#include<iostream>
#include<algorithm>
#include<vector>
#include<iomanip>
#include<set>
using namespace std;

int main(){
    ios::sync_with_stdio(false);
    int N, M; cin >> N;
    vector<set<int>> SET;
    for(int i = 0; i != N; ++i){
        cin >> M;
        set<int> vec;
        for(int j = 0; j != M; ++j){
            int X; cin >> X;
            vec.insert(X);
        }
        SET.push_back(vec);
    }

    int K; cin >> K;
    for(int i = 0; i != K; ++i){
        if(i != 0) cout << '\n';
        int x, y; cin >> x >> y; x -= 1, y -= 1;
        set<int> cnt1(SET[x]), cnt2(SET[y]);
        vector<int> A, B;
        set_intersection(cnt1.begin(), cnt1.end(), cnt2.begin(), cnt2.end(), insert_iterator<vector<int>>(A,A.begin()));
        set_union(cnt1.begin(), cnt1.end(), cnt2.begin(), cnt2.end(), insert_iterator<vector<int>>(B,B.begin()));
        
        cout << setprecision(2) << fixed << (double) A.size() / B.size() * 100 << '%';
    }  
}
上一篇:期末预测之最佳阈值


下一篇:C++中++cnt1[s1[i]-'a']的意思