蓝桥杯匹配对局Java
#问题描述
小明喜欢在一个围棋网站上找别人在线对弈。这个网站上所有注册用户都有一个积分,代表他的围棋水平。
小明发现网站的自动对局系统在匹配对手时,只会将积分差恰好是K的两名用户匹配在一起。如果两人分差小于或大于K,系统都不会将他们匹配。
现在小明知道这个网站总共有N名用户,以及他们的积分分别是A1, A2, … AN。
小明想了解最多可能有多少名用户同时在线寻找对手,但是系统却一场对局都匹配不起来(任意两名用户积分差不等于K)?
参考代码
第一次上传 注释写的很详细 希望大家可以看懂
package 算法训练;
import java.util.Scanner;
public class 对局匹配 {
// 10 1
// 1 4 2 8 5 7 1 4 2 8
//
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 输入玩家数量
int n = sc.nextInt();
// 记录玩家积分最大值 后面会用到遍历有效数组长度
int maxx = Integer.MIN_VALUE;
// 输入积分差
int k = sc.nextInt();
// 开辟一个存储用户积分的数组 用来保存数据
int [] arr = new int[n];
// 记录移除玩家个数 玩家总数减去cnt就是answer了
int cnt = 0;
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
// 不断地更新maxx
if(maxx<arr[i]) maxx = Math.max(maxx,arr[i]);
}
// 开辟辅助空间 由题目的数据规模决定开辟空间的大小
// 但实际遍历的时候我们直到maxx
// 开这么大为了防止积分差值k很大 匹配相加的时候数组越界
int [] helper = new int [1000000];
for (int i = 0; i < n; i++) {
// 将玩家积分数值转下标 每次出现下标位置++
// 记录当前积分值有多少名玩家
helper[arr[i]]++;
}
for (int i = 0; i <=maxx; i++) {
// 如果说k不等0 且只要满足while条件说明能匹配到玩家
while(helper[i]>0&&helper[i+k]>0&&k!=0){
// 这里是本题难点所在 干掉两名玩家 但是计数只加一
cnt++;
helper[i]--;//A玩家
helper[i+k]--;//B玩家
// AB玩家互相消耗 直到A==0 或者B==0
}
// 如果说k==0 也就是说不能匹配相同积分玩家的最多用户数
if(k==0&&helper[i]>=2){
// 记录干掉了多少名玩家 但是要保留一名
cnt+=helper[i]-1;
// 留下一名玩家
helper[i] = 1;
}
}
System.out.println(n-cnt);
// System.out.println(Arrays.toString(helper));
}
}