题目
分析
题意是给出若干个数的集合,然后根据给出的集合编号,让我们所给编号集合的相似度,相似度的计算方式是(两个集合的共有数字的个数)/ (两个集合加起来不同数字的个数),格式为百分数形式,保留一位小数。
解题过程
一开始看题有点懵,shared by two sets 和 in the two sets 没理解好,耗费了一点时间去百度翻译。然后就会理解到每个集合的重复的元素是没有价值的,于是就想到用set去解决。
- 第一步,利用set去装给出的集合的数,又因为vector装啥都行,首选创建vector去装set。
- 第二步,共有数字的个数该怎么求呢,翻译为人话就是在A集合里有在B集合也有的数,所以运用set的函数find()就非常舒服。
- 第三步,两个集合总共不同数字的个数怎么求,很简单,因为set有自动去重的功效,所以先拿一个集合的大小size为基础,然后再求第二步的时候只要不共有那就是不同,那就可以再size的基础上加一即可。
- 请观看代码:
#include<iostream>
#include<set>
#include<vector>
using namespace std;
int main()
{
int n, m, k, a, b, temp, num;
scanf("%d", &n);
vector<set<int> > v(n);
for(int i = 0; i < n; i++)
{
set<int> s;
scanf("%d", &num);
for(int j = 0; j < num; j++)
{
scanf("%d", &temp);
s.insert(temp);
}
v[i] = s;
}
scanf("%d", &k);
for(int i = 0; i < k; i++)
{
scanf("%d %d", &a, &b);
int nc = 0, nt = v[b-1].size(); // 注意这行和下一行,如果你拿了A集合为基础size,那么下面你就要在B集合里找有没有A集合的数,所以是it = B 的begin(),反之也是,因为A集合不一定能包含B集合的所有数。
for(auto it = v[a-1].begin(); it != v[a-1].end(); it++)
{
if(v[b-1].find(*it) == v[b-1].end()) nt++;
else nc++;
}
double ans = (double)nc / nt * 100;
printf("%.1lf%%\n", ans);
}
return 0;
}
小结
- set是STL里唯一可以find()value的神器,可以轻易的找到真值。
- vector挺万能的,装啥都行,功能又多,以后首选vector不要数组啦。