题目已经告诉我们了,C++的STL set 是不二之选。两个set,交集中的元素个数 / 并集中的元素个数就是我们需要的结果。
set求交并集在<Algorithm>头文件里已实现,用法如下:
set<int> U, I; // 分别保存并集、交集结果
// 并集
set_union(S[s1].begin(), S[s1].end(), S[s2].begin(), S[s2].end(), inserter(U, U.begin()));
// 交集
set_intersection(S[s1].begin(), S[s1].end(), S[s2].begin(), S[s2].end(), inserter(I, I.begin()));
// 打印结果
printf("%.1f%%\n", 100.0*(float)(I.size()) / (float)(U.size()));
注意,求交并集函数的前四个参数为两个集合的开始和结束位置迭代器,最后一个迭代器为结果集合的插入迭代器,inserter定义在<iterator>头文件中。
另外一个小问题就是用printf输出百分号时,printf("%%")打印1个%,相应的,printf("%%%%")打印2个%。百分号比较特殊,不能用转义字符。
题目不难,空间和时间都足够。主要考察set的基本用法。AC代码如下:
#include<stdio.h>
#include<set>
#include<iterator>
#include<algorithm>
using namespace std;
set<int> S[51];
int main()
{
int N;
scanf("%d", &N);
for (int i = 1; i <= N; i++)
{
int M;
scanf("%d", &M);
for (int j = 0; j < M; j++)
{
int tmp;
scanf("%d", &tmp);
S[i].insert(tmp);
}
}
int K;
scanf("%d", &K);
for (int i = 0; i < K; i++)
{
int s1, s2;
scanf("%d %d", &s1, &s2);
set<int> U, I;
set_union(S[s1].begin(), S[s1].end(), S[s2].begin(), S[s2].end(), inserter(U, U.begin()));
set_intersection(S[s1].begin(), S[s1].end(), S[s2].begin(), S[s2].end(), inserter(I, I.begin()));
printf("%.1f%%\n", 100.0*(float)(I.size()) / (float)(U.size()));
}
return 0;
}