需要考慮幾個點:
紅包形成的隊列不應該是從小到大或者從大到小,需要有大小的隨機性。
紅包這種金錢類的需要用Decimal保證精確度。
考慮紅包分到每個人手上的最小的最大的情況。
下面是利用線段分割算法實現的分紅包, 比如把100元紅包,分給十個人,就相當於把(0-100)這個線段隨機分成十段,也就是再去中找出9個隨機點。
找隨機點的時候要考慮碰撞問題,如果碰撞了就重新隨機(當前我用的是這個方法)。這個方法也更方便抑制紅包金額MAX情況,如果金額index-start>MAX,就直接把紅包設為最大值MAX,
然后隨機點重置為start+MAX,保證所有紅包金額相加等於總金額。
import java.math.BigDecimal; import java.util.*; public class RedPaclage{ public static List<Integer> divideRedPackage(int allMoney, int peopleCount,int MAX) { //人數比錢數多則直接返回錯誤 if(peopleCount<1||allMoney<peopleCount){ System.out.println("錢數人數設置錯誤!"); return null; } List<Integer> indexList = new ArrayList<>(); List<Integer> amountList = new ArrayList<>(); Random random = new Random(); for (int i = 0; i < peopleCount - 1; i++) { int index; do{ index = random.nextInt(allMoney - 2) + 1; }while (indexList.contains(index));//解決碰撞 indexList.add(index); } Collections.sort(indexList); int start = 0; for (Integer index:indexList) { //解決最大紅包值 if(index-start>MAX){ amountList.add(MAX); start=start+MAX; }else{ amountList.add(index-start); start = index; } } amountList.add(allMoney-start); return amountList; } public static void main(String args[]){ Scanner in=new Scanner(System.in); int n=Integer.parseInt(in.nextLine()); int pnum=Integer.parseInt(in.nextLine()); int money=n*100;int max=n*90; List<Integer> amountList = divideRedPackage(money, pnum,max); if(amountList!=null){ for (Integer amount : amountList) { System.out.println("搶到金額:" + new BigDecimal(amount).divide(new BigDecimal(100))); } } } }