题目
Given two sets of integers, the similarity of the sets is defined to be , where is the number of distinct common numbers shared by the two sets, and 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
which is the total number of sets. Then N lines follow, each gives a set with a positive
and followed by M integers in the range
. After the input of sets, a positive integer
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%
解题思路
题目大意: 给定N个集合,求任意连个集合的交集元素比上并集元素个数的比值。
解题思路: 这道题的思路并不难,关键在于怎么实现集合的交集和并集,以及如何实现集合。直接使用stl中的set能够快速的解决这一问题。我们直接在此基础上统计不同的元素个数,即得到集合交集的元素个数,然后,我们直接用两个集合元素个数之和减去交集个数,得到并集个数,最后直接比值即可。
/*
** @Brief:No.1063 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2018-12-28
** @Solution: https://blog.csdn.net/CV_Jason/article/details/85329420
*/
#include<iostream>
#include<set>
#include<map>
using namespace std;
int main(){
int N,M,K,temp;
while(scanf("%d",&N)!=EOF){
set<int> st[N];
for(int i=0;i<N;i++){
scanf("%d",&M);
for(int j=0;j<M;j++){
scanf("%d",&temp);
st[i].insert(temp);
}
}
int a,b;
scanf("%d",&K);
for(int i=0;i<K;i++){
scanf("%d%d",&a,&b);
int nc=0,nt=0;
for(auto it = st[a-1].begin();it!=st[a-1].end();it++){
if(st[b-1].find(*it)!=st[b-1].end()){
nc++;
}
}
nt = st[b-1].size()+st[a-1].size()-nc;
printf("%.1f%%\n",nc*100.0/nt);
}
}
return 0;
}
总结
最开始用set+map的组合进行集合运算,使用map是为了方便统计不同元素的个数,用元素出现次数作为value,结果最后一个点超时了,由于我对set和map的时空性能不是很熟悉,看了别人的答案,有set+find算法过的,看来map还是很耗时的。