PAT-A 1063. Set Similarity (25)

一道STL(set)的练习题。

set翻译为集合,是一个内部自动有序不含重复元素的容器,这是set非常重要的特性,要在实际问题中充分利用之。

除此之外,值得注意的是,set的基本操作:insert()、find()等一些操作的时间复杂度为O(logN)。


题目链接在此

题意

给出N个集合,然后有K个查询,给出每个查询的Set Similarity,即(Nc/Nt)*100.0。Nc为两个集合的交集的元素个数,Nt为两个集合的并集的元素个数。

思路及实现

刚开始有两种想法:

  1. 想法一:对于交集,自己实现一个求交集的函数,时间复杂度到了O(N^2);对于并集,则利用set的特性,将两个集合放到一个set中,即可得到并集。
  2. 想法二:直接利用< algorithm >头文件中的set_union()、set_intersection()求得并集和交集

实践证明,以上两种方法都会有一组测试点超时。

那么如何降低求交集和并集的时间复杂度呢?想想上面提到的set的find()操作,它的时间复杂度达到了O(logN)。

以下是程序的正确思路,时间复杂度为O(NlogN):

  1. 用一个set数组sets保存所有输入的集合
  2. 要查询的两个集合分别为sets[a]、sets[b]
  3. 初始化Nc=0, Nt=sets[b].size()(集合b的元素个数)
  4. 然后一边遍历集合a,一边用find()操作在集合b中查找是否在b中也存在某元素,若存在,则Nc++,若不存在,则Nt++。最后即可求得所求比值。
#include<stdio.h>
#include<set>
#include<algorithm>

using namespace std;

const int N = 51;
set<int> sets[N];

void getNcAndNt(int a, int b, int &nc, int &nt){  //求集合a与集合b的nc和nt 
    for(set<int>::iterator ita = sets[a-1].begin(); ita != sets[a-1].end(); ita++){
        if(sets[b-1].find(*ita) != sets[b-1].end()){   //在b集合中能找到该元素 
            nc++;
        }else{          //在b集合中不能找到该元素 
            nt++;
        }
    }
}

int main(){

    int n;   // total number of set
    scanf("%d",&n);

    for(int i = 0; i < n; i++){     //get sets
        int num;
        scanf("%d", &num);

        for(int j = 0; j < num; j++){
            int temp;
            scanf("%d", &temp);
            sets[i].insert(temp);
        }
    } 

    //获取查询并求并集和交集个数
    int query;
    scanf("%d", &query);
    for(int i = 0; i < query; i++){
        int a,b;
        scanf("%d %d",&a, &b);

        int nc = 0,nt = sets[b-1].size();  //交集个数,并集个数  
        getNcAndNt(a, b, nc, nt);

        printf("%.1lf%%\n", nc*100.0/nt);
    } 


    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值