每个测试文件均包含多组测试数据。第一行输入一个整数
代表数据组数,每组测试数据描述如下:
第一行输入一个整数
代表账号数量。
第二行输入
个整数
代表账号权重。
除此之外,保证单个测试文件的
之和不超过
。
对于每组测试数据,新起一行。输出一个整数,代表包含账号数量最多的社交网络中,包含的账号数量。
2 5 2 1 6 7 16 2 2 16
4 1
对于第一组测试数据,连接示意图如下图所示:
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Main {
/**
* 合并社交圈,计算最大社交圈的大小
* 使用位运算表示用户的兴趣标签,通过或运算合并有共同兴趣的社交圈
*
* @param interests 每个用户的兴趣标签数组(用long的二进制位表示)
* @param userCount 用户数量
*/
public static void mergeSocialCircles(long[] interests, int userCount) {
// 使用Map表示社交圈:key为社交圈的标签(所有用户兴趣的或运算结果),value为该社交圈的用户数量
Map<Long, Integer> socialCircles = new HashMap<>();
int maxCircleSize = 0; // 记录最大社交圈的大小
for (int i = 0; i < userCount; i++) {
long currentInterest = interests[i];
long mergedInterest = currentInterest; // 合并后的兴趣标签
int mergedCount = 1; // 合并后的用户数量,初始为当前用户自己
// 遍历现有社交圈,查找与当前用户有共同兴趣的圈子
// 注意:这里使用临时数组来避免在遍历时修改Map
Long[] existingCircles = socialCircles.keySet().toArray(new Long[0]);
for (Long circleInterest : existingCircles) {
// 检查当前用户兴趣与社交圈兴趣是否有交集(按位与结果不为0)
if ((currentInterest & circleInterest) != 0) {
// 合并兴趣标签(按位或)
mergedInterest |= circleInterest;
// 累加用户数量
mergedCount += socialCircles.get(circleInterest);
// 移除被合并的社交圈
socialCircles.remove(circleInterest);
}
}
// 将合并后的社交圈加入Map
socialCircles.put(mergedInterest, mergedCount);
// 更新最大社交圈大小
maxCircleSize = Math.max(maxCircleSize, mergedCount);
}
System.out.println(maxCircleSize);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取测试用例数量
int testCaseCount = scanner.nextInt();
for (int i = 0; i < testCaseCount; i++) {
// 读取当前测试用例的用户数量
int userCount = scanner.nextInt();
long[] interests = new long[userCount];
// 读取每个用户的兴趣标签
for (int j = 0; j < userCount; j++) {
interests[j] = scanner.nextLong();
}
// 处理当前测试用例
mergeSocialCircles(interests, userCount);
}
scanner.close();
}
}