L2-005 集合相似度-PAT團體程序設計天梯賽GPLT

題目來源:團體程序設計天梯賽-練習集
題目地址:L2-005 集合相似度

problem

題目大意

給定 nn 個集合,然後有 kk 次詢問,每次詢問都要求出 Nc/Nt×100%N_c / N_t \times100\%

NcN_c 表示兩個集合中都有的數的個數(重複不計),相當於求交集去重
NtN_t 表示兩個集合一共有多少個數(重複不計),相當於求並集去重

題目分析

根據題意,我們在存儲集合就時候就可以將重複元素去掉,可以用上C++ STL提供的 setset 容器,它不會保存重複元素。
1
設要求的兩個集合分別爲 AABB,它們的大小分別爲 SizeASize_ASizeBSize_B

我們先遍歷集合 AA ,每訪問一個元素就判斷它是否在集合 BB中出現,如果出現,則計數器 cntcnt 加一,最後得出的 cntcnt 就是 NcN_c

因爲有 cntcnt 個數在集合 AA 出現一遍,又在集合 BB 中出現了一遍,所以求 NtN_t 的時候我們需要將它減去,最後我們得到求 NtN_t 的式子如下:
Nt=SizeA+SizeBcntN_t=Size_A+Size_B-cnt

代碼如下

#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;
}

如果本文對你有所幫助,記得要點贊哦~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章