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);
}
}