题目描述
给出两个数集,它们的相似程度定义为 Nc/Nt×100。其中,Nc 表示两个数集中相等的、两两互不相同的元素个数,而 Nt 表示两个数集中总共的互不相同的元素个数。请计算任意两个给出数集的相似程度。
输入
第一行一个正整数 N(N≤50),表示数集的个数。
接下来的 N 行,每行首先给出一个正整数 M(M≤10000),之后给出的 M 个正整数为此数集中的元素(可能有重复,小于或等于 106)。
在这些数集之后,给出一行一个正整数 K(K≤2000) 表示询问的个数。
之后的 K 行,每行两个正整数 x 和 y,表示询问 x 数集与 y 数集的相似程度。每一行中输入的各个整数之间由一个空格隔开。
输出
对于每一个询问,输出一行一个百分数,为两个数集的相似程度,保留一位小数。
样例输入
3
3 99 87 101
4 87 101 5 87
7 99 101 18 5 135 18 99
2
1 2
1 3
样例输出
50.0%
33.3%
数据规模与约定
时间限制:11 s
内存限制:256 M
思路:
直接用stl里的set存放集合,然后计算相同元素个数和总的不同元素个数
代码(一):
#include<iostream>
#include<cstdio>
#include<set>
using namespace std;
set<int>w[52];
int main() {
int n , m, t, k, a, b;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &m);
while(m --) {
scanf("%d", &t);
w[i].insert(t);
}
}
scanf("%d", &k);
while(k --) {
scanf("%d%d", &a, &b);
int ia = w[a].size(), ib = w[b].size(), sum = 0;
for(set<int>::iterator it = w[a].begin(); it != w[a].end(); it++) {
if(w[b].count(*it)) sum++;
}
printf("%.1f%%\n", sum * 100.0 / (ia + ib - sum));
}
return 0;
}
用set仍然Time Limit Exceeded一组!
代码(二):
在algorithm中有set_union(并集),set_intersection(交集),set_difference(差集)
3 个函数的写法
set_??(a.begin(),a.end(),b.begin(),b.end(),inserter(x,x.begin());
#include<iostream>
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
set<int>w[52];
int main() {
int n , m, t, k, a, b;
scanf("%d", &n);
for(int i = 1; i <= n; i++) {
scanf("%d", &m);
while(m --) {
scanf("%d", &t);
w[i].insert(t);
}
}
scanf("%d", &k);
while(k --) {
scanf("%d%d", &a, &b);
int ia = w[a].size(), ib = w[b].size(), sum = 0;
set<int>s;
set_intersection(w[a].begin(),w[a].end(),w[b].begin(),w[b].end(),inserter(s,s.begin()));
sum = s.size();
printf("%.1f%%\n", sum * 100.0 / (ia + ib - sum));
}
return 0;
}