L2-005. 集合相似度

来源:互联网 发布:php redis auth 编辑:程序博客网 时间:2024/06/11 04:36

L2-005. 集合相似度

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

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

输入格式:

输入第一行给出一个正整数N(<=50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(<=104),是集合中元素的个数;然后跟M个[0, 109]区间内的整数。

之后一行给出一个正整数K(<=2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。

输出格式:

对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。

输入样例:
33 99 87 1014 87 101 5 877 99 101 18 5 135 18 9921 21 3
输出样例:
50.00%33.33%

提交代码

解题思路:
本题可以使用两种方法。
方法一:
set有一个很好的去重功能,不会把重复的节点算进去,先定义一个set数组,然后把每个集合的数据存入相应的数组。最后求相似度的时候定义两个vector,分别存储两者都有的和两者所有的元素。然后再使用两个函数把数据放入这两个数组。这种方法需要对STL的内容较为熟悉,这两个函数也是特定的求相交于合并的函数,虽然效率高,但比较偏,不建议使用
#include<iostream>#include<cstring>#include<cstdio>#include<set>#include<algorithm>#include<vector>using namespace std;#define N 100int main(){//freopen("input.txt","r",stdin);int n,m,a,b;set<int>s[N];scanf("%d",&n);for(int i = 1;i <= n;i++){scanf("%d",&m);for(int j = 0;j < m;j++){int num;scanf("%d",&num);s[i].insert(num);//把相应元素放入相应集合 }}scanf("%d",&n);for(int i = 0;i < n;i++){scanf("%d%d",&a,&b);vector<int>s1,s2;//算出并集 set_union(s[a].begin(),s[a].end(),s[b].begin(),s[b].end(),back_inserter(s1));//算出交集 set_intersection(s[a].begin(),s[a].end(),s[b].begin(),s[b].end(),back_inserter(s2));printf("%.2f%%\n",((s2.size())*1.0)/s1.size()*100);}return 0;} 

方法二:
前面部分和方法一完全相同,在求并集和交集那里不同,依次拿集合a中的元素到集合b中去查找,如果找到了,sum加一,后面用两个集合的元素总量减sum的值就是两者都有的值,方法二较为容易使用和理解,建议使用方法二
#include<iostream>#include<cstring>#include<cstdio>#include<set>#include<algorithm>using namespace std;#define N 100int main(){//freopen("input.txt","r",stdin);int n,m,a,b;set<int>s[N];scanf("%d",&n);for(int i = 1;i <= n;i++){scanf("%d",&m);for(int j = 0;j < m;j++){int num;scanf("%d",&num);s[i].insert(num);//把相应元素放入相应集合 }}scanf("%d",&n);for(int i = 0;i < n;i++){scanf("%d%d",&a,&b);set<int>::iterator ite;int sum = 0;for(ite = s[a].begin();ite != s[a].end();ite++){if(s[b].find(*ite) != s[b].end()){//判断集合a中的元素是否在集合b中出现过 sum++;}}printf("%.2f%%\n",sum*1.0/(s[a].size()+s[b].size()-sum)*100);}return 0;} 


原创粉丝点击