题目描述
给定两个整数集合,它们的相似度定义为:。其中 是两个集合都有的不相等整数的个数, 是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
输入格式:
输入第一行给出一个正整数 ,是集合的个数。随后 行,每行对应一个集合。每个集合首先给出一个正整数 ,是集合中元素的个数;然后跟 个 区间内的整数。
之后一行给出一个正整数 ,随后 行,每行对应一对需要计算相似度的集合的编号(集合从 到 编号)。数字间以空格分隔。
输出格式:
对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后 位的百分比数字。
输入样例:
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
输出样例:
50.00%
33.33%
题目分析
本题为 PTAl2 的一道题目,考察的是对 STL 工具的运用。
解如题意,即求两个集合各自的不同整数的数量,然后再求其交集数量为 ,求其并集数量为 。最终用 printf 输出包含小数的答案。
一开始,我对每次枚举的两个集合使用 求得答案,相关代码如下:
map<int, bool> p1, p2;
for (int i = 1; i <= cnt[x]; i ++)
p1[a[x][i]] = true;
int nc = 0, nt = p1.size();
for (int i = 1; i <= cnt[y]; i ++)
{
if (p2[a[y][i]]) continue;
if (p1[a[y][i]]) nc ++;
else nt ++;
p2[a[y][i]] = true;
}
但对于最后一个测试点的反馈为 TLE。
随后我尝试使用 预处理每个集合的不重复数字集,随后却得到了错误答案,经过多次测试,发现在 if(p1[x][a[x][i]]) 后,当反馈为 时,p1[x].size() 会自加一,即当下次再用到当前 时,初始化的 nt = p1.size() 会出错。
后来我尝试使用 这个 进行储存,最终通过此题。
Accept代码
#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 1e4 + 10;
set<int> p[N];
int cnt[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n; cin >> n;
for (int i = 1; i <= n; i ++)
{
int s; cin >> s;
for (int j = 0; j < s; j ++)
{
int x; cin >> x;
p[i].insert(x);
}
cnt[i] = p[i].size();
}
int k; cin >> k;
while (k --)
{
int x, y;
cin >> x >> y;
int nc = 0, nt = cnt[x];
for (auto i : p[y])
{
if (p[x].count(i)) nc ++;
else nt ++;
}
printf("%.2f%\n", (double)nc / nt * 100);
}
return 0;
}