1063 Set Similarity——PAT甲级(双解法)

Given two sets of integers, the similarity of the sets is defined to be Nc​/Nt​×100%, where Nc​ is the number of distinct common numbers shared by the two sets, and Nt​ 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%

 

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

输入格式:

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

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

输出格式:

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

solution1:
 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
int main()
{
	int n;cin>>n;
	unordered_set<int>s[51];
	for(int k=0;k<n;k++)
	{
		int t;cin>>t;
		while(t--)
		{
			int tmp;cin>>tmp;
			s[k].insert(tmp);
		}
	}
	int k;cin>>k;
	for(int p=0;p<k;p++)
	{
		int a,b;
		cin>>a>>b;
		a-=1;b-=1;
		int cnt=0;
		for(auto it:s[a])
		{
			if(s[b].count(it))
			{
				cnt++;
			}
		}
		double ans=(double)cnt/(s[a].size()+s[b].size()-cnt);
		ans*=100;
		printf("%.1f%%\n",ans);
	}
}

 solution2:
用交集与并集函数计算

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
int main()
{
	int n;cin>>n;
	vector<vector<int> >v(n);
	for(int i=0;i<n;i++)
	{
		int k;cin>>k;
		vector<int>t(k);
		for(int j=0;j<k;j++)cin>>t[j];
		v[i]=t;
		sort(v[i].begin(),v[i].end());
	}
	int k;cin>>k;
	while(k--)
	{
		int a,b;cin>>a>>b;
		a-=1;b-=1;
		vector<int>same,all;
		set_intersection(v[a].begin(),v[a].end(),v[b].begin(),v[b].end(),inserter(same,same.begin()));
		set_union(v[a].begin(),v[a].end(),v[b].begin(),v[b].end(),inserter(all,all.begin()));
		same.erase(unique(same.begin(),same.end()),same.end());
		all.erase(unique(all.begin(),all.end()),all.end());
		double ans=(double)same.size()/all.size()*100;
		printf("%.1f%%\n",ans);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值