【题目描述】:某商场开业举行线上活动,期中就包括了盲盒抽取,正常的实物抽取是在一个奖池里面随机抽取一个,而该商场的应用系统是通过概率结合数目进行抽取,请完成该抽奖算法: 要求: 1、可设置盲盒的总数,三个奖励级别的数目以及对应的抽取概率 2、抽取数目等于盲盒总数后需要把各级别消耗完 3、输出每次执行抽取的结果,以及当前剩余的各个级别奖品的数目 进阶要求: 设置样本数大于200,一等奖3个,二等奖20个,抽取算法使用概率结合保底的策略,不在奖品数组上面去随机,实现20次至少3等奖,30次至少2等奖的保底策略。并在输出展示哪一次触发保底策略。
时间: 2023-03-29 20:01:31 浏览: 243
我可以回答这个问题。这是一个抽奖算法的问题,要求设置盲盒的总数,三个奖励级别的数目以及对应的抽取概率,并且抽取数目等于盲盒总数后需要把各级别消耗完。进阶要求是设置样本数大于200,一等奖3个,二等奖20个,抽取算法使用概率结合保底的策略,实现20次至少3等奖,30次至少2等奖的保底策略,并在输出展示哪一次触发保底策略。
相关问题
写出下面的源代码:【题目描述】:某商场开业举行线上活动,期中就包括了盲盒抽取,正常的实物抽取是在一个奖池里面随机抽取一个,而该商场的应用系统是通过概率结合数目进行抽取,请完成该抽奖算法: 要求: 1、可设置盲盒的总数,三个奖励级别的数目以及对应的抽取概率 2、抽取数目等于盲盒总数后需要把各级别消耗完 输出每次执行抽取的结果,以及当前剩余的各个级别奖品的数目
好的,以下是 Java 代码实现盲盒抽奖的算法,可以根据题目要求进行修改:
```java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BlindBox {
private int totalNum; // 盲盒总数
private List<Integer> levelNums; // 奖励级别的数量
private List<Double> levelProbs; // 奖励级别的抽取概率
private Random random; // 随机数生成器
public BlindBox(int totalNum, List<Integer> levelNums, List<Double> levelProbs) {
this.totalNum = totalNum;
this.levelNums = levelNums;
this.levelProbs = levelProbs;
this.random = new Random();
}
/**
* 抽奖算法
* @return 抽取的奖品级别
*/
public int draw() {
double rand = random.nextDouble(); // 生成一个随机数
double probsSum = 0.0;
for (int i = 0; i < levelProbs.size(); i++) {
probsSum += levelProbs.get(i);
if (rand < probsSum) {
int level = i + 1;
if (levelNums.get(level - 1) > 0) {
levelNums.set(level - 1, levelNums.get(level - 1) - 1); // 更新奖品列表中对应级别的数量
return level;
} else {
return draw(); // 如果该级别的奖品已经被抽完,则重新抽取
}
}
}
return -1; // 如果所有级别的奖品都被抽完了,则返回-1
}
/**
* 盲盒抽奖主程序
*/
public void run() {
int drawCount = 0;
while (totalNum > 0) {
int level = draw();
if (level > 0) {
System.out.println("第" + (++drawCount) + "次抽奖,获得了" + level + "等奖");
totalNum--;
}
}
System.out.println("抽奖结束,各个级别奖品的剩余数量为:" + levelNums);
}
public static void main(String[] args) {
int totalNum = 100;
List<Integer> levelNums = new ArrayList<>();
levelNums.add(10);
levelNums.add(20);
levelNums.add(totalNum - 10 - 20); // 三个奖励级别的数目
List<Double> levelProbs = new ArrayList<>();
levelProbs.add(0.1);
levelProbs.add(0.2);
levelProbs.add(0.7); // 对应的抽取概率
BlindBox blindBox = new BlindBox(totalNum, levelNums, levelProbs);
blindBox.run();
}
}
```
该程序定义了一个 `BlindBox` 类,包含了盲盒总数、奖励级别的数量和抽取概率等属性,以及抽奖算法和盲盒抽奖的主程序。在 `main` 方法中构造了一个 `BlindBox` 对象,并调用其 `run` 方法执行盲盒抽奖。
java程序4.盲盒抽取 【题目描述】:某商场开业举行线上活动,期中就包括了盲盒抽取,正常的实物抽取是在一个奖池里面随机抽取一个,而该商场的应用系统是通过概率结合数目进行抽取,请完成该抽奖算法: 要求: 1、可设置盲盒的总数,三个奖励级别的数目以及对应的抽取概率2抽取数目等于盲盒总数后需要把各级别消耗完 3、输出每次执行抽取的结果,以及当前剩余的各个级别奖品的数目进阶要求: 设置样本数大于200,一等奖3个,二等奖20个,抽取算法使用概率结合保底的策略,不在奖品数组上面去随机,实现20次至少3等奖,30次至少2等奖的保底策略。并在输出展示哪一次触发保底策略。
好的,我会尽力回答您的问题。针对您的问题,我可以提供以下的思路和代码实现:
思路:
1. 首先,我们需要定义盲盒的总数,以及三个奖励级别的数目和对应的抽取概率。
2. 然后,我们可以使用Java的随机数生成器来模拟抽奖过程,根据各个奖品的概率来计算抽中的概率。
3. 在进行抽奖的同时,我们需要根据已经抽中的奖品数量,来判断当前剩余的各个级别奖品的数目是否为0,如果为0,就需要将其从奖池中剔除。
4. 最后,我们可以输出每次执行抽取的结果,以及当前剩余的各个级别奖品的数目。
代码实现:
```java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class BlindBox {
// 盲盒总数
private int totalNum;
// 一等奖数目
private int prize1Num;
// 二等奖数目
private int prize2Num;
// 三等奖数目
private int prize3Num;
// 一等奖概率
private double prize1Prob;
// 二等奖概率
private double prize2Prob;
// 三等奖概率
private double prize3Prob;
// 奖品池
private List<Integer> pool;
// 随机数生成器
private Random random;
public BlindBox(int totalNum, int prize1Num, int prize2Num, int prize3Num, double prize1Prob, double prize2Prob, double prize3Prob) {
this.totalNum = totalNum;
this.prize1Num = prize1Num;
this.prize2Num = prize2Num;
this.prize3Num = prize3Num;
this.prize1Prob = prize1Prob;
this.prize2Prob = prize2Prob;
this.prize3Prob = prize3Prob;
this.pool = new ArrayList<>();
this.random = new Random();
initPool();
}
// 初始化奖品池
private void initPool() {
for (int i = 0; i < prize1Num; i++) {
pool.add(1);
}
for (int i = 0; i < prize2Num; i++) {
pool.add(2);
}
for (int i = 0; i < prize3Num; i++) {
pool.add(3);
}
}
// 抽奖
public int draw() {
if (pool.isEmpty()) {
return 0;
}
int index = random.nextInt(pool.size());
int prize = pool.get(index);
pool.remove(index);
updatePrizeNum(prize);
return prize;
}
// 更新奖品数量
private void updatePrizeNum(int prize) {
switch (prize) {
case 1:
prize1Num--;
break;
case 2:
prize2Num--;
break;
case 3:
prize3Num--;
break;
}
}
// 获取一等奖概率
public double getPrize1Prob() {
return prize1Prob;
}
// 获取二等奖概率
public double getPrize2Prob() {
return prize2Prob;
}
// 获取三等奖概率
public double getPrize3Prob() {
return prize3Prob;
}
public static void main(String[] args) {
// 盲盒总数
int totalNum = 200;
// 一等奖数目
int prize1Num = 3;
// 二等奖数目
int prize2Num = 20;
// 三等奖数目
int prize3Num = totalNum - prize1Num - prize2Num;
// 一等奖概率
double prize1Prob = 0.01;
// 二等奖概率
double prize2Prob = 0.1;
// 三等奖概率
double prize3Prob = 1 - prize1Prob - prize2Prob;
BlindBox box = new BlindBox(totalNum, prize1Num, prize2Num, prize3Num, prize1Prob, prize2Prob, prize3Prob);
int prize1Count = 0; // 一等奖数量
int prize2Count = 0; // 二等奖数量
int count = 0; // 抽奖次数
while (true) {
int prize = box.draw();
count++;
if (prize == 1) {
prize1Count++;
} else if (prize == 2) {
prize2Count++;
}
// 判断是否触发保底策略
if (count == 20 && prize3Count(box) < 3) {
System.out.println("第" + count + "次抽奖触发了保底策略(至少3个三等奖)");
break;
}
if (count == 30 && prize2Count < 2) {
System.out.println("第" + count + "次抽奖触发了保底策略(至少2个二等奖)");
break;
}
if (prize1Count == 3 && prize2Count == 20 && prize3Count(box) == 0) {
System.out.println("恭喜您,已经抽完了所有奖品!");
break;
}
}
}
// 计算剩余三等奖数量
private static int prize3Count(BlindBox box) {
double prob = box.getPrize3Prob();
int count = box.pool.size();
int prize1Count = box.prize1Num;
int prize2Count = box.prize2Num;
int prize3Count = count - prize1Count - prize2Count;
int minCount = (int) Math.ceil((box.totalNum - prize1Count - prize2Count) * prob);
if (prize3Count < minCount) {
prize3Count = minCount;
}
return prize3Count;
}
}
```
注意事项:
1. 为了实现保底策略,我们需要在抽奖过程中判断已经抽中的奖品数量,因此每次抽奖后都需要更新奖品数量。
2. 在判断是否触发保底策略时,我们需要计算当前剩余的三等奖数量是否已经达到保底要求。
3. 为了实现保底策略,我们还需要在计算剩余三等奖数量时,根据概率来计算最少需要保留的数量。
希望这个答案能够帮助到您!
阅读全文