题目链接
注意点:
1.要滤掉集合中的相同元素,因此使用set比较方便。
2.比较两集合时因遍历其中一个集合的每个元素,与另一个集合中的元素比较,用find()来查找时间复杂度可以到O(n(a)logn(b)),如果处理两个集合,时间复杂度会到O(N^2),最后一个样例会超时。
AC代码:
#include<cstdio>
#include<set>
using namespace std;
set<int> sets[55];//集合的集合
int main(){
int n;
scanf("%d",&n);//输入集合数
for(int i=1;i<=n;i++){//建立集合
int m,t;
scanf("%d",&m);
for(int j=0;j<m;j++){
scanf("%d",&t);
sets[i].insert(t);
}
}
int query;
scanf("%d",&query);//查询数
for(int i=0;i<query;i++){
int a,b;
scanf("%d %d",&a,&b);//查询数组对的序号
int totalnum=sets[a].size(),common=0;
//totalnum是总元素的个数,即不同元素的个数,common是相同元素的个数
for(set<int>::iterator it=sets[b].begin();it!=sets[b].end();it++){
//对b集合中的每个元素进行比较
if(sets[a].find(*it)!=sets[a].end()) {
//该元素在集合a中出现
common++;//相同元素时加1
}
else totalnum++;//否则不同元素数加1
}
printf("%.1lf%%\n",(float)common/totalnum*100);
//输出百分号要用两个%%
//计算比值
}
return 0;
}
贴一下处理两个集合的比较函数。该函数的思想是将两个集合中的元素合并到一个集合中,插入后合并集合大小不变,则说明有相同元素。该算法时间复杂度为O((n(a)+n(b))(log(n(a)+n(b))),会超时。
void compare(int a,int b){
set<int>::iterator temp;
set<int>::iterator ita=sets[a].begin();
set<int>::iterator itb=sets[b].begin();
while(ita!=sets[a].end()||itb!=sets[b].end()){
int tempsize=temp.size();
if(ita!=sets[a].end()) {
temp.insert(*ita);
if(temp.size()==tempsize) common++;
ita++;
}
tempsize=temp.size();
if(itb!=sets[b].end()) {
temp.insert(*itb);
if(temp.size()==tempsize) common++;
itb++;
}
}
printf("%.1lf%%\n",(float)common/temp.size()*100);
}