蓝桥杯匹配对局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));
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值