做这道题的感觉就很玄学
之前代码一直跑不过去,然后今天就突然跑过去了
感觉自己也就优化了一点点啊
开始分析
题目的难点在于对于题目的解读上
给定两个整数集合,它们的相似度定义为:Nc/Nt×100%。
其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。
你的任务就是计算任意一对给定集合的相似度。
一开始我想的比较复杂,我以为一个集合里如果有重复数字就直接删掉(包括原数字)
经过测试后发现不对,实际上,题目的意思是
两个集合的交集除以并集,集合不含重复数字
也就是直接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 << '%';
}
}