首页 > 其他分享 >L2-005 集合相似度

L2-005 集合相似度

时间:2023-01-03 12:02:14浏览次数:40  
标签:set int scanf sum2 sum1 L2 005 集合


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

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

输入格式:

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

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

输出格式:

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

输入样例:

3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3

输出样例:

50.00%
33.33%

思路 

题意很短,所以要看清。

两个集合都有的不相等整数的个数 等价于 两个集合的交集

两个集合一共有的不相等整数的个数等价于 两个集合的并集

注意:上边说的是集合,但是输入的数据有重复的。

所以用c++就用stl set集合就行了。

第一次写的时候,我是先放在数组中,然后再放到set中进行去重。因为这个数据量 不小,所以最后一组数据超时。

那我们输入的时候就直接放到set中,这样就节省了很多时间

代码

AC的代码

#include<cstdio>
#include<set>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 50 + 5;
set<int> s[maxn];
set<int>::iterator it;

double solve(int p, int q){
int sum1 = 0;
int sum2 = 0;
for(it = s[p].begin(); it != s[p].end(); it++){
int p = *it;;
if(s[q].find(p) != s[q].end()){
sum1++;
}
}
sum2 = s[p].size() + s[q].size() - sum1;
return (sum1*1.0)/(sum2*1.0)*100;
}

int main(){
int n,t,p,q;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%d",&t);
for(int j = 1; j <= t; j++){
int temp;
scanf("%d",&temp);
s[i].insert(temp);
}
}
scanf("%d",&t);
while(t--){
scanf("%d%d",&p,&q);
printf("%.2lf%%\n",solve(p,q));

}
return 0;
}

超时的代码

#include<cstdio>
#include<set>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn = 50 + 5;
int a[maxn][maxn];
set<int> s1,s2;
set<int>::iterator it1;
set<int>::iterator it2;

double solve(int p, int q){
int sum1 = 0;
int sum2 = 0;
s1.clear();
s2.clear();
for(int i = 1; i <= a[p][0];i++){
s1.insert(a[p][i]);
}
for(int i = 1; i <= a[q][0];i++){
s2.insert(a[q][i]);
}
for(it1 = s1.begin(); it1 != s1.end(); it1++){
int p = *it1;;
if(s2.find(p) != s2.end()){
sum1++;
}
}
sum2 = s1.size() + s2.size() - sum1;
return (sum1*1.0)/(sum2*1.0)*100;
}

int main(){
int n,t,p,q;
scanf("%d",&n);
memset(a,-1,sizeof(a));
for(int i = 1; i <= n; i++){
scanf("%d",&a[i][0]);
for(int j = 1; j <= a[i][0] ; j++){
scanf("%d",&a[i][j]);
}
}
scanf("%d",&t);
while(t--){
scanf("%d%d",&p,&q);
printf("%.2lf%%\n",solve(p,q));

}
return 0;
}

 

标签:set,int,scanf,sum2,sum1,L2,005,集合
From: https://blog.51cto.com/u_13758447/5985141

相关文章

  • NumPy科学计算库学习_005_关于NumPy数组的运算
    导入模块importnumpyasnp创建两个NumPy数组arr1=np.array([1,2,3,4,5])arr2=np.array([3,4,5,6,7])print("【arr1】\n",arr1)print("【arr2】\n",arr2)【a......
  • 天梯赛练习题L2(011-015)
    L2-011玩转二叉树#include<bits/stdc++.h>usingnamespacestd;typedeflonglongLL;typedefpair<LL,LL>PII;constLLMAXN=1e18;constLLN=500200,M=4002;//u......
  • 数据结构 玩转数据结构 7-9 Leetcode上更多集合和映射的问题
    0课程地址https://coding.imooc.com/lesson/207.html#mid=13711 1重点关注1.1结论3.1和3.2对比3.2空间复杂度优于3.1 3.3和3.4对比......
  • 当下适合男人用的智能手机集合-转
    哪些智能手机适合男人使用呢?哪些安卓手机具有男人气息呢?从低价位的1000到中高价位的4000均有推荐,有兴趣的朋友不妨考虑一下。 HTC7Trophy,也叫奖杯,WP7系统,1000......
  • 第十三章《集合》第5节:Map集合
    ​List、Set和Queue都是Collection接口的子接口,因此从更高层次来说它们属于统一类型的集合。Map接口也代表一种集合,但它不是Collection子接口,因此它属于另一种类型的集合。M......
  • 第十三章《集合》第6节:使用Collections类操作集合
    ​Java提供了一个操作集合的工具类Collections,这个类中提供了大量方法对集合元素进行排序、查询和修改等操作,此外还提供了将集合对象设置为不可变、对集合对象实现同步控制......
  • 第十三章《集合》第4节:Queue集合
    ​Queue是一个接口,它也是Collection接口的子接口。Queue用来模拟队列这种数据结构。队列这种数据结构最明显的特征是元素先入先出,队列的头部的元素是所有元素中最先进入队列......
  • 第十三章《集合》第2节:List集合
    ​List这个单词意为“列表”,List类型的集合的特点是:元素呈线性排列,致密且有序。下面的图13-3展示了List类型集合的特点。图13-3List类型集合​图13-3中的每一个小圆形代表......
  • 第十三章《集合》第3节:Set集合
    ​Set也是Collection的子接口,它定义了另一种形式的集合,专业上称之为Set集合。Set集合的特点如图13-9所示。图13-9Set类型集合​从图13-9可以看出:Set类型的集合就像是一个装......
  • Java Map 集合类简介
    java.util中的集合类包含Java中某些最常用的类。最常用的集合类是List和Map。List的具体实现包括ArrayList和Vector,它们是可变大小的列表,比较适合构建、存储和......