题目描述
知识点
STL中的无序集合unordered_set
我的实现
码前思考
这里我使用的是暴力遍历两个set
到一个set
里面,然后比较前后值的个数的变化,得到公共的部分。
需要注意的是,千万不能两层for
循环遍历,那样绝对会超时!
代码实现
//交集除以并集再乘100%
//数组下标从1开始
#include <iostream>
#include <unordered_set>
#include <algorithm>
using namespace std;
const int maxn = 55;
unordered_set<int> sts[maxn];
unordered_set<int> uni;
int main(){
int n;
scanf("%d",&n);
int m,tmp;
for(int i=1;i<=n;i++){
scanf("%d",&m);
for(int j=0;j<m;j++){
scanf("%d",&tmp);
sts[i].insert(tmp);
}
}
int k;
scanf("%d",&k);
int u,v;
for(int i=0;i<k;i++){
scanf("%d %d",&u,&v);
uni.clear();
int preTot = sts[u].size()+sts[v].size();
for(unordered_set<int>::iterator it = sts[u].begin();it!=sts[u].end();it++){
uni.insert(*it);
}
for(unordered_set<int>::iterator it = sts[v].begin();it!=sts[v].end();it++){
uni.insert(*it);
}
int afterTot = uni.size();
int uniTot = preTot-afterTot;
printf("%.1f",1.0*uniTot/afterTot*100);
cout<<"%"<<endl;
}
return 0;
}
码后反思
我看了看我去年的代码,使用的是通过find()
来实现的,但是我就的set
的find()
的时间复杂度为O(logn)
的(它是就与BST),所以与两层for
循环没啥区别吧,不知道为啥能过,但是如果用unordered_set
,估计性能会好一点,它的find()
最低是O(1)~O(n)
,这个是常见的考点啊。
//注意运行超时的情况,使用find来查找元素相同的情况
#include<stdio.h>
#include<set>
using namespace std;
set<int> stArray[55];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
int m;
scanf("%d",&m);
for(int j=0;j<m;j++){
int input=0;
scanf("%d",&input);
stArray[i].insert(input);
}
}
int k;
scanf("%d",&k);
for(int i=0;i<k;i++){
set<int> tmp;
int a,b;
scanf("%d %d",&a,&b);
int sa = stArray[a].size();
int sb = stArray[b].size();
int common = 0;
for(set<int>::iterator it=stArray[a].begin();it!=stArray[a].end();it++){
int now = *(it);
if(stArray[b].find(now) != stArray[b].end()){ //if we can't find,then the iterator's value will be stArray[b].end()!!!
common++;
}
}
// for(set<int>::iterator it=stArray[b].begin();it!=stArray[b].end();it++){
// tmp.insert(*it);
// }
// int sc = tmp.size();
// double per = (double)(sa+sb-sc) / sc * 100;
double per = (double)(common) / (sa+sb-common) * 100;
printf("%.1f%%",per);
if(i!=k-1){
printf("\n");
}
}
return 0;
}