L2-005 集合相似度-PAT团体程序设计天梯赛GPLT

本文介绍了一种使用C++ STL set容器高效计算集合相似度的方法,通过遍历集合并利用set的特性去除重复元素,实现对两个集合的交集和并集的计算,进而求得集合相似度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目来源:团体程序设计天梯赛-练习集
题目地址:L2-005 集合相似度

problem

题目大意

给定 n n n 个集合,然后有 k k k 次询问,每次询问都要求出 N c / N t × 100 % N_c / N_t \times100\% Nc/Nt×100%

N c N_c Nc 表示两个集合中都有的数的个数(重复不计),相当于求交集去重
N t N_t Nt 表示两个集合一共有多少个数(重复不计),相当于求并集去重

题目分析

根据题意,我们在存储集合就时候就可以将重复元素去掉,可以用上C++ STL提供的 s e t set set 容器,它不会保存重复元素。
1
设要求的两个集合分别为 A A A B B B,它们的大小分别为 S i z e A Size_A SizeA S i z e B Size_B SizeB

我们先遍历集合 A A A ,每访问一个元素就判断它是否在集合 B B B中出现,如果出现,则计数器 c n t cnt cnt 加一,最后得出的 c n t cnt cnt 就是 N c N_c Nc

因为有 c n t cnt cnt 个数在集合 A A A 出现一遍,又在集合 B B B 中出现了一遍,所以求 N t N_t Nt 的时候我们需要将它减去,最后我们得到求 N t N_t Nt 的式子如下:
N t = S i z e A + S i z e B − c n t N_t=Size_A+Size_B-cnt Nt=SizeA+SizeBcnt

代码如下

#include <bits/stdc++.h>

using namespace std;
int n, m, t, k, a, b;
const int maxn = 1e4 + 10;
/**
  * 利用stl中set来进行集合的存储
  */
set<int> vis[maxn];
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &m);
        while (m--) {
            scanf("%d", &t);
            vis[i].insert(t);
        }
    }
    scanf("%d", &k);
    while (k--) {
        scanf("%d %d", &a, &b);
        // set.size() 返回的是集合中不同元素的个数
        int cnt1 = vis[a].size(), cnt2 = vis[b].size(), cnt3 = 0;
        for (auto e : vis[a]) {
            if (vis[b].count(e))
                cnt3++;
        }
        printf("%.2f%\n", (double)cnt3 / (cnt1 + cnt2 - cnt3) * 100);
    }
    return 0;
}

如果本文对你有所帮助,记得要点赞哦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值