题目内容:
解题思路:
我在处理本题的时候,最开始粗读题目,为它设置的是 vector<vector <int> > 进行存储,但是在后续处理同集合内不相等整数时遇到很大的麻烦。
所以我认为本题难点有三个:
难点1:读懂题目中所说的 “其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。” 这句话。
难点2:将两个集合中相同数据判断出来并记录,同时它不能重复,也就是求出Nc。
难点3:同一个集合中的数据要保持相异,也就是求出Nt。
然后对于每一个难点,我会提供我的处理方式。
首先,对于读懂题目,我以输入案例的第二种情况为例,其中 99 , 101在两个集合中都存在,故 Nc 值为2, 同时这两个数就不算在 Nt 的值,在第三个集合中有两个 99 和 18 ,而99在第一个集合中出现,18没有在第一个集合中出现,能记一个Nt的值,故Nt值为 6 。
其次,对于难点2,可以使用 find 函数进行查找,遍历第一个集合,在第二个集合进行查找,并记录。
对于难点3,我的处理方法是使用 set 的结构进行存储,因为set会过滤掉重复的数据。
C++代码展示:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m; // 定义变量n(集合的数量)和m(查询的次数)
set<int> num[55]; // 定义一个大小为55的set数组,用于存储每个集合
cin >> n;
for (int i = 1; i <= n; i++) {
int a;
cin >> a;
for (int j = 0; j < a; j++) {
int b;
cin >> b;
num[i].insert(b); // 将元素插入对应的集合中
}
}
cin >> m;
for (int i = 0; i < m; i++) {
int f, s; // 定义变量f和s,用于存储每次查询的两个集合的索引
cin >> f >> s; // 读取每次查询的两个集合的索引
int sum = num[f].size() + num[s].size(); // 计算两个集合的大小之和
int same = 0; // 定义变量same,用于存储两个集合的交集的大小
for (auto j : num[f]) { // 遍历第一个集合中的每个元素
if (num[s].find(j) != num[s].end()) { // 如果元素也在第二个集合中
same++; // 交集的大小加1
}
}
printf("%.2f%%\n", 1.0 * same / (sum - same) * 100);//输出相似度百分比,保留两位小数
}
return 0;
}