平均分组 java_平均分组问题(Java实现)

本文介绍了如何使用Java解决平均分组问题,考虑了负数分数的情况,并提供了详细的解题思路和完整代码示例,包括如何对选手进行排序、计算平均分以及交换分组策略,以使各组实力接近。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、平均分组问题(Java实现)

题目

按分数对选手进行平均分组,可分多组。

注意:

输入的选手名单players为集合形式,player表示选手名称,score表示选手的分数

选手的分数体现选手的实力,分数有可能是负数

最终解不是唯一,但要求分组后,每组的实力尽量接近,每组的人数也尽量接近

例如:

将所有选手,总共7人

[

{

"player": "a",

"score": 22

},

{

"player": "b",

"score": -9

},

{

"player": "c",

"score": 13

},

{

"player": "d",

"score": 17

},

{

"player": "e",

"score": 0

},

{

"player": "f",

"score": -11

},

{

"player": "g",

"score": -2

}

]

复制代码

1、如果分成两组,应该是4 VS 3 的队形

[

[

{

"player": "a",

"score": 22

},

{

"player": "e",

"score": 0

},

{

"player": "g",

"score": -2

},

{

"player": "f",

"score": -11

}

],

[

{

"player": "d",

"score": 17

},

{

"player": "c",

"score": 13

},

{

"player": "b",

"score": -9

}

]

]

复制代码

2、如果分成三组,应该是3 VS 2 VS 2的队形

[

[

{

"player": "a",

"score": 22

},

{

"player": "b",

"score": -9

},

{

"player": "f",

"score": -11

}

],

[

{

"player": "c",

"score": 13

},

{

"player": "e",

"score": 0

}

],

[

{

"player": "d",

"score": 17

},

{

"player": "g",

"score": -2

}

]

]

复制代码

​不知道大家第一次看到这代题目时候,是怎么想的。请大家先想一下,不要着急看我的思路和代码,这样容易顺着我的思路走,应该有自己的思路与想法,如果没有,再参考我的解决思路。

解题思路:

​首先可以确定的是这道题是有可能无法得到最优解的,只能得到一个接近最优解的解或最优解。

1、 先按照选手的分数按照正序或者倒叙进行排序,我这里按照倒叙排列。

2、 求出所有选手的总分数,然后求出平均数。

3、 将选手分成两组,例如组一,组二,然后用组一的分值最小的选手去和组二中分值最大的选手进行交换

4、如果交换后组一的总分数大于平均数,那么进行交换,直至出现临界值,当组一的总分数小于平均分值,即分组成功

1、要注意分组中负数的存在,负数会越加越小

2、为什么用组一的分值最小的选手去和组二中分值最大的选手进行交换

因为可以使组一的分值缓慢下降,直至出现组一的分值大于平均值。 否则快速下降,很难确定临界值

Java代码:

下面是我的代码,如果有什么不足的地方或者错误的地方,欢迎指出。

```java

package com.kxj;

/**

* @ClassName GroupingDemo

* @Description TODO

* @Author kongxiangjin

* @Date 2019/10/15 16:13

* @Version 1.0

**/

import java.util.ArrayList;

import java.util.Collections;

import java.util.List;

public class GroupingDemo {

/**

* 选手集合

*/

private static List players = new ArrayList<>();

public static void main(String[] args) {

// 初始化选手

Player player1 = new Player("a", 22);

Player player2 = new Player("b", -9);

Player player3 = new Player("c", 13);

Player player4 = new Player("d", 17);

Player player5 = new Player("e", 0);

Player player6 = new Player("f", -11);

Player player7 = new Player("g", -2);

players.add(player1);

players.add(player2);

players.add(player3);

players.add(player4);

players.add(player5);

players.add(player6);

players.add(player7);

//选手总人数

int count = players.size();

//总分数

double sum = sumMethod(players);

//分组数

int groupNum = 2;

//平均数

double average = sum / groupNum;

//每组人数

int num = count / groupNum;

//double diff = sum;

boolean flag = false;

//倒叙

Collections.sort(players);

List groupList1 = new ArrayList<>();

List groupList2 = new ArrayList<>();

for (int i = 0; i < num; i++) {

groupList1.add(players.get(i));

}

for (int i = num; i < count; i++) {

groupList2.add(players.get(i));

}

for (int i = 0; i < groupList2.size(); ) {

// 先取出第二组中最大的选手

Player p2 = groupList2.get(i);

for (int j = groupList1.size() - 1; j >= 0; j--) {

// 集合中的对象进行交换

Player p1 = groupList1.get(j);

groupList1.remove(p1);

groupList1.add(p2);

groupList2.remove(p2);

groupList2.add(p1);

double sum1 = sumMethod(groupList1);

// double sum2 = sumMethod(groupList2);

// 如果交换后的数据不满足条件,说明上一个值即为临界值,则进行回退

if (sum1 > average && j != 0) {

groupList1.remove(p2);

groupList1.add(p1);

groupList2.remove(p1);

groupList2.add(p2);

} else if (sum1 > average && j == 0) {

break;

} else {

// 找到临界值后跳出循环

flag = true;

break;

}

}

if (flag == true) {

System.out.println(groupList1);

System.out.println(groupList2);

break;

}

// 每次循环需要对组一进行重新排序,再交换的过程中,原先的倒叙会被打乱。

Collections.sort(groupList1);

}

}

/**

* 求总分数

* @param players

* @return

*/

private static double sumMethod(List players) {

double sum = 0;

for (Player player : players) {

sum += player.getScore();

}

return sum;

}

}

```

```java

package com.kxj;

/**

* @ClassName Player

* @Description TODO

* @Author kongxiangjin

* @Date 2019/10/15 16:14

* @Version 1.0

**/

public class Player implements Comparable {

private String name;

private int score;

public Player() {

}

public Player(String name, int score) {

this.name = name;

this.score = score;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getScore() {

return score;

}

public void setScore(int score) {

this.score = score;

}

@Override

public int compareTo(Player o) {

return o.score - this.score;

}

@Override

public String toString() {

return "Player{" +

"name='" + name + '\'' +

", score=" + score +

'}';

}

}

```

复制代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值