给定两个整数集合,它们的相似度定义为:Nc/Nt×100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
输入格式:
输入第一行给出一个正整数N(≤50),是集合的个数。随后N行,每行对应一个集合。每个集合首先给出一个正整数M(≤104),是集合中元素的个数;然后跟M个[0,109]区间内的整数。
之后一行给出一个正整数K(≤2000),随后K行,每行对应一对需要计算相似度的集合的编号(集合从1到N编号)。数字间以空格分隔。
输出格式:
对每一对需要计算的集合,在一行中输出它们的相似度,为保留小数点后2位的百分比数字。
输入样例:
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%
解题思路
它们的相似度定义为:Nc/Nt×100%。其中Nc是两个集合都有的不相等整数的个数,Nt是两个集合一共有的不相等整数的个数。你的任务就是计算任意一对给定集合的相似度。
解题过程中遇到的问题
最后还是会存在运行超时问题,暂无找到解决的方法
解题代码
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
int n = Integer.parseInt(br.readLine()); // 读取集合的数量
ArrayList<HashSet<Integer>> sets = new ArrayList<>();
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int m = Integer.parseInt(st.nextToken()); // 读取当前集合的元素数量
HashSet<Integer> set = new HashSet<>();
for (int j = 0; j < m; j++) {
int num = Integer.parseInt(st.nextToken()); // 读取元素
set.add(num);
}
sets.add(set);
}
int k = Integer.parseInt(br.readLine()); // 读取需要计算相似度的集合对数量
for (int i = 0; i < k; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken()) - 1; // 转换为索引
int b = Integer.parseInt(st.nextToken()) - 1;
HashSet<Integer> setA = sets.get(a);
HashSet<Integer> setB = sets.get(b);
int commonElements = 0; // 交集元素数量
// 计算交集元素数量
if (setA.size() < setB.size()) {
for (Integer num : setA) {
if (setB.contains(num)) {
commonElements++;
}
}
} else {
for (Integer num : setB) {
if (setA.contains(num)) {
commonElements++;
}
}
}
int totalElements = setA.size() + setB.size() - commonElements; // 并集的元素数量
double similarity = 100.0 * commonElements / totalElements; // 相似度
out.printf("%.2f%%\n", similarity);
}
out.flush();
out.close();
}
}