题目


解法1

点击查看代码
#include <iostream>
#include <set>
#include <vector>
#include <cstdio>

using namespace std;

int main() {
    int n;
    scanf("%d", &n);
    vector<set<int>> vs(n);
    
    // 读取 n 个集合
    for (int i = 0; i < n; i++) {
        int m;
        scanf("%d", &m);
        while (m--) {
            int num;
            scanf("%d", &num);
            vs[i].insert(num);
        }
    }

    int q;
    scanf("%d", &q);
    
    while (q--) {
        int s1, s2;
        scanf("%d %d", &s1, &s2);
        s1--; s2--;  // 题目集合编号从 1 开始,转成 0-based 索引
        
        // 计算 Nc(交集大小)
        int Nc = 0;
        if (vs[s1].size() > vs[s2].size()) { // 遍历较小集合,加速查找
            for (auto num : vs[s2]) {
                if (vs[s1].find(num) != vs[s1].end()) {
                    Nc++;
                }
            }
        } else {
            for (auto num : vs[s1]) {
                if (vs[s2].find(num) != vs[s2].end()) {
                    Nc++;
                }
            }
        }

        // 计算 Nt(并集大小)
        int Nt = vs[s1].size() + vs[s2].size() - Nc;

        // 计算相似度并格式化输出
        double similarity = (Nc * 100.0) / Nt;
        printf("%.1f%%\n", similarity);
    }

    return 0;
}
---