题目描述
给定两个整数集合,两个集合的相似度定义为 Nc/Nt×100%,其中 Nc 是两个集合中都存在的不同整数的数量,Nt 是两个集合中不同整数的数量。
现在,请你计算给定集合的相似度。
输入格式
第一行包含整数 N,表示集合数量。
接下来 N 行,每行包含一个集合的信息,首先包含一个整数 M,表示集合中的数的个数,然后包含 M 个整数,表示集合中的每个元素。
再一行,包含整数 K,表示询问次数。
接下来 K 行,每行包含一组询问,包括两个整数 a 和 b,表示询问集合 a 和集合 b的相似度。
所有集合的编号为 1∼N
输出格式
每行输出一个询问的结果,保留一位小数。
输出答案与标准答案的绝对误差不超过 0.10.1 即视为正确。
数据范围
1≤N≤50,
1≤M≤10000,
1≤K≤2000,
集合中的元素取值均在 [0,109][0,109] 范围内。
输入样例:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
输出样例:
50.0%
33.3%
这道题我用到了两种方法,一种是哈希表一种是数组。
哈希表
#include<iostream>
#include<bits/stdc++.h>
#include<map>
#define N 100
using namespace std;
int main(){
unordered_set<int> mp[N];
int n,m,k,a,b,sum,ans=0;
double d;
cin>>n;
for(int i=1;i<=n;i++){
cin>>m;
while(m--){
cin>>a;
mp[i].insert(a);
}
}
cin>>k;
while(k--){
ans=0;
cin>>a>>b;
for(unordered_set<int>::iterator it=mp[a].begin();it!=mp[a].end();it++){
if(mp[b].count(*it))
ans++;
}
sum=mp[b].size()+mp[a].size()-ans;
if(ans>sum)
d=1;
else
d=(ans*1.0)/sum;
d=d*100;
cout<<fixed<<setprecision(1)<<d<<"%"<<endl;
}
return 0;
}
数组
这种方法时间复杂度较高不建议使用
#include<iostream>
#include<map>
#include<bits/stdc++.h>
const int N=1e4+10;
using namespace std;
int str[N][N];
int main(){
int n,m,a,b,sum=0,ans=0;
double d;
cin>>n;
for(int i=1;i<=n;i++){
cin>>str[i][0];
for(int j=1;j<=str[i][0];j++){
cin>>str[i][j];
}
}
cin>>n;
while(n--){
map<int,int> mp,arr;
sum=0;ans=0;
cin>>a>>b;
for(int i=0;i<=str[a][0];i++){
if(mp[str[a][i]]==0)
mp[str[a][i]]++;
}
for(int i=0;i<=str[b][0];i++){
if(mp[str[b][i]]==1){
ans++;
mp[str[b][i]]=2;
}
if(mp[str[b][i]]==0){
sum++;
mp[str[b][i]]=-1;
}
if(arr[str[b][i]]==0)
arr[str[b][i]]++;
}
for(int i=0;i<=str[a][0];i++){
if(arr[str[a][i]]==0){
sum++;
arr[str[a][i]]=3;
}
}
if(ans>sum)
d=100;
else{
d=(ans*1.0)/sum;
d=d*100;
}
cout<<fixed<<setprecision(1)<<d<<"%"<<endl;
}
return 0;
}
关于这两道题的写法已经讲解完毕,希望对各位有用,谢谢大家