小Hi开发了一个在线玩斗地主的游戏平台。现在平台上有N名用户正在寻找对局,其中第i名用户的积分是Ai。
小Hi希望自己的平台可以自动将这N名用户匹配成尽量多的3人牌局。同时他希望一局中的3名用户两两之间的积分差不超过K。
你能帮小Hi实现这个自动对局匹配的算法吗?
假设现在正有7人在寻找对局,积分分别是[30, 31, 30, 34, 33, 32, 34]并且K = 1,这时最多可以匹配出2局:[30, 31, 30]和[34, 33, 34]。
Input第一行包含两个整数,N和K。 (1 ≤ N ≤ 100000, 1 ≤ K ≤ 100000)
第二行包含N整数Ai。(0 ≤ Ai ≤ 100000)
Output一个整数表示最多能匹配出的对局数量。
7 2 30 31 30 34 33 32 34Sample Output
2
题目的关键是先排序,因为你总会担心,当一个人可以加入多个队时,应该怎么选择,所以要先排序,这样序列才不会混乱,否则如果不排序就直接找
6 1
31 32 31 32 30 30这个样例可能过不了
一排序更加相近的数就会组在一起了,这很关键!
并且排完序后两两之间的差值只要最大的和最小的满足就ok了,我开了结构体里面有个fou变量来表示当前这个数是否已被组队.当全部组队完成后把这三个玩家的fou置为true,表示已经组队成功
#include <bits/stdc++.h>
using namespace std;
const int inf = 1e5 + 10;
struct node{
int val;
bool fou;
}th[inf];
bool tmp(node x, node y)
{
return x.val < y.val;
}
int main()
{
int n, ans = 0,k, tot = 1;
scanf("%d %d", &n, &k);
for(int i = 0; i < n; i ++){
scanf("%d", &th[i].val);
th[i].fou = false;
}
sort(th, th + n, tmp);
int xu[3];
for(int i = 0; i < n; i ++){
if(th[i].fou) continue;
xu[0] = i;
for(int j = i + 1; j < n; j ++){
if(abs(th[i].val - th[j].val) <= k){
xu[tot] = j;
tot ++;
}else {
tot = 1;
break;
}
if(tot == 3){
tot = 1;
ans ++;
for(int z = 0; z < 3; z ++){
th[xu[z]].fou = true;
}
break;
}
}
}
cout << ans << endl;
return 0;
}