题目大意:给出N个集合,输出指定集合 m 和 n 的相似度。所谓相似度,是指 集合 m 和 n 中公共的元素的个数(不重复),占 m 和 n中所有不同元素个数的百分比。
可以直接用set<int> 存储 集合 m 和 n,之后将它们的元素再插入一个新的集合中,这样可以得到它们总的不重复元素个数和公共元素个数。不过这样虽然在PAT能过,牛客网上会超时。所以需要找到时间复杂度更低的方法。
依然是用set<int>存储集合 m 和 n,由于set本身有序,可以用双指针,依次比较 m 和 n 的当前元素,当前元素相等则重复元素数+1,否则小的那一方指针后移,直到一个集合遍历完毕。
另外注意格式化输出%的写法是%%。
AC代码:
#include <vector>
#include <cstdio>
#include <set>
using namespace std;
int main()
{
int N, K;
scanf("%d", &N);
vector<set<int>> v(N+1);
for (int i = 1; i <= N; ++i)
{
int count;
scanf("%d", &count);
for (int j = 0; j < count; ++j)
{
int num;
scanf("%d", &num);
v[i].insert(num);
}
}
scanf("%d", &K);
for (int query = 0; query < K; ++query)
{
int p, q;
scanf("%d%d", &p, &q);
int sameCnt = 0;
set<int>::iterator ip = v[p].begin(), iq = v[q].begin();
while(ip != v[p].end() && iq != v[q].end())
{
if(*ip < *iq) ip++;
else if(*ip > *iq) iq++;
else
{
sameCnt++;
ip++;
iq++;
}
}
printf("%.1f%%\n", sameCnt * 1.0 / (v[p].size() + v[q].size() - sameCnt) * 100);
}
return 0;
}