1063 Set Similarity (25 分)

1063 Set Similarity (25 分)

Given two sets of integers, the similarity of the sets is defined to be N**c/N**t×100%, where N**c is the number of distinct common numbers shared by the two sets, and N**t is the total number of distinct numbers in the two sets. Your job is to calculate the similarity of any given pair of sets.

Input Specification:

Each input file contains one test case. Each case first gives a positive integer N (≤50) which is the total number of sets. Then N lines follow, each gives a set with a positive M (≤104) and followed by M integers in the range [0,109]. After the input of sets, a positive integer K (≤2000) is given, followed by K lines of queries. Each query gives a pair of set numbers (the sets are numbered from 1 to N). All the numbers in a line are separated by a space.

Output Specification:

For each query, print in one line the similarity of the sets, in the percentage form accurate up to 1 decimal place.

Sample Input:

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

Sample Output:

50.0%
33.3%

分析:

​ 最开始我实现的代码是开了三个set,将要比较的第一个放入s1,要比较的第二个放入s2,同时把这一对要比较的都放入s中,这样set会自动降重,我们最后输出的时候只需要把s1.size()+s2.size()-s.size()除以s.size()就可以了,但是最后一个测试点超时了,我看了下算法笔记的题解,发现实现了一个compare函数,将两个需要比较的set集合使用find函数遍历了一次,来查重计算totalnum和samenum,理论上多遍历了一次需要比较的序列,但是最后一个测试点没有超时,暂时没有想清楚原因…如果想清楚了,再来填坑…

修改前:

#include<bits/stdc++.h>
using namespace std;
int a[55][10005];
int m[10005];
int main(){
	
	int n;
	scanf("%d",&n);
	
	for(int i=1;i<=n;i++){
	    cin>>m[i];
	    for(int j=0;j<m[i];j++){
	    	scanf("%d",&a[i][j]);
		}
	}
	int k;
	cin>>k;
	for(int i=0;i<k;i++){
		set<int> s,s1,s2;
		int b1,b2;
		scanf("%d%d",&b1,&b2);
     
		for(int i=0;i<m[b1];i++){
			s1.insert(a[b1][i]);
			s.insert(a[b1][i]);
		}
		for(int i=0;i<m[b2];i++){
			s2.insert(a[b2][i]);
			s.insert(a[b2][i]);  
           
		}
	
		int tmp1=s1.size()+s2.size()-s.size();
		int tmp2=s.size();
		double res=(double)tmp1/tmp2*100;
		printf("%.1f%\n",res);
	}
	
	
} 

在这里插入图片描述

修改后:

#include<bits/stdc++.h>
using namespace std;
const int N=51;
set<int> s[N];

void compare(int a,int b){
	int totalnum=s[a].size(),samenum=0;
	for(set<int>::iterator it=s[b].begin();it!=s[b].end();it++){
		if(s[a].find(*it)!=s[a].end())//找到了
		    samenum++;
		else totalnum++; 
	}
	double res=(double)samenum/totalnum*100;
	printf("%.1f%\n",res);
}

int main(){
	
	int n;
	scanf("%d",&n);
	
	for(int i=1;i<=n;i++){
	    int m;cin>>m;
	    for(int j=0;j<m;j++){
	    	int tmp;
	    	scanf("%d",&tmp);
	    	s[i].insert(tmp);
		}
	}
	int k;	cin>>k;
	for(int i=0;i<k;i++){
		int b1,b2;
		scanf("%d%d",&b1,&b2);
		compare(b1,b2); 		
	}
} 

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值