【1063 25 set】 Set Similarity
传送门
题意
给定 \(n\) 个集合,每个集合里面输入 \(m\) 个数 \(a_{i}\),给定 \(k\) 个查询,输入 \(l,r\) 根据集合 \(l,r\) 求出 \(N_{c}\) 即两个集合共有的数,\(N_{t}\) 两个集合合并后的不同的数,求出 \(N_{c}/N_{t}\),结果以百分号形式输出,并保留 \(1\) 位小数
数据范围
\(n\leq 50\)
\(m\leq 10^{4}\)
\(a_{i}\in [0,10^{9}]\)
\(k\leq 2000\)
题解
- 用 set 自动去重特性存储
- 每次查询初始化 \(N_{t}\) 为 set[r] 的数量
- 遍历 set[l] 利用 find 函数查找当前值,如果 set[r] 中不存在那么nt++,存在的话即公共值 nc++
- 因为 set 内部是有序的,find 基于二分每次查询为 \(O(nlogn)\)
Code
#include<bits/stdc++.h>
using namespace std;
#define in insert
#define sz size
map<int,bool>mp;
int main(){
ios::sync_with_stdio(0); cin.tie(0);
int n; cin>>n;
set<int>s[n+1];
for(int i=1;i<=n;i++){
int m; cin>>m;
for(int j=0;j<m;j++) { int x; cin>>x; s[i].in(x); }
}
int k; cin>>k;
while(k--){
int l,r; cin>>l>>r;
int nc=0,nt=s[r].sz();
for(auto it:s[l]) {
if(s[r].find(it)==s[r].end()) nt++;
else nc++;
}
double ans=(double)nc/nt*100;
printf("%.1lf%%\n",ans);
}
}

浙公网安备 33010602011771号