问题:

一副扑克牌,除去大小王后共52张牌,随机从中抽八张牌,问八张牌的和最有可能是多少?

分析:

这52张牌,其实就是数字 1 2 3 。。。13, 每个数字出现4次。随机抽出8个数,问组成的和最有可能是多少?

很快想到了2种方法:

1.根据 大数定理 ,多次模拟抽牌,求和,看和的分布情况

2.在所有的C(52,8)种情况中,求出所有89(12-100)种情况和的组合数

解法1:

首先生成一副扑克牌,放入list中,每次随机取出一张牌后,list remove该元素,代码如下:

 package test;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class LargeNumbersTest { public static int getSum() {
//生成一副扑克牌,放入list
List<Integer> list=new ArrayList<Integer>();
for(int i=1;i<14;i++){
list.add(i);
list.add(i);
list.add(i);
list.add(i);
} int[] a=new int[8];
for(int i=0;i<8;i++){
int random=(int)(Math.random()*list.size());
//随机取出一张牌,并在list集合中去除对应的数
a[i]=list.get(random);
list.remove(random);
}
int sum=0;
for(int i=0;i<a.length;i++){
sum+=a[i];
}
return sum;
}
public static void main(String[] args) {
Map<Integer,Integer> map=new HashMap<Integer, Integer>();
//多次重复试验
for(int i=0;i<1000000;i++){
int key=getSum();
//试验结果存入map中,记录出现的次数
if(map.keySet().contains(key)){
map.put(key, map.get(key)+1);
}else{
map.put(key, 1);
}
}
//输出map集合,本来想写一个按值排序的方法,搜了一下,太麻烦,果断放弃,改用excel处理结果
for(Integer key:map.keySet()){
System.out.println(map.get(key)+"\t"+key);
}
}
}

运行5次后,输出结果在excel中排序,如下:

可以看出,和是56的结果最多,大概39800,(只要三万九千八,求和结果带回家。。。),根据大数定理,估计和最可能的数是 56 ,概率约等于 0.0398,

但是,和为57、55出现的次数也比较接近 56 ,是不是概率相等呢?

我们求一下每种情况的准确概率(大数定理只能估算概率),请看解法2。

解法2:

模拟计算机抽牌的每一种情况,求出每一种情况下的和。

1.如果按照每张牌的点数分类的话,每次抽牌都要考虑这张牌的点数 在本次抽牌中 出现的次数,太麻烦,所以对每张牌进行编号(0-51),

问题转化为:在0-51中取出8个不同的数字,并对这8个数字代表的点数 求和。

2.8个数字,8个变量,8次循环,感觉很low啊,不过我没想到好的办法,就先这样吧,希望大家找到好的办法能分享给我。

代码如下:

 package test;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class PokerTest {
public static void main(String[] args) {
//生成一副扑克牌,放入list
List<Integer> list=new ArrayList<Integer>();
for(int i=1;i<14;i++){
list.add(i);
list.add(i);
list.add(i);
list.add(i);
}
int count=0;
Map<Integer,Integer> map=new HashMap<Integer, Integer>();
//模拟每一种抽牌结果,low到爆的8次循环
for(int a1=0;a1<45;a1++){
for(int a2=a1+1;a2<46;a2++){
for(int a3=a2+1;a3<47;a3++){
for(int a4=a3+1;a4<48;a4++){
for(int a5=a4+1;a5<49;a5++){
for(int a6=a5+1;a6<50;a6++){
for(int a7=a6+1;a7<51;a7++){
for(int a8=a7+1;a8<52;a8++){
int sum=list.get(a1)+list.get(a2)
+list.get(a3)+list.get(a4)
+list.get(a5)+list.get(a6)
+list.get(a7)+list.get(a8);
//记录抽牌总次数
count++;
//抽牌结果记录到map中,并记录次数
if(map.keySet().contains(sum)){
map.put(sum, map.get(sum)+1);
}else{
map.put(sum, 1);
}
}
}
}
}
}
}
}
}
for(Integer key:map.keySet()){
System.out.println(map.get(key)+"\t"+key);
}
System.out.println("count===="+count);
} }

结果依然是输出到excel中处理,

首先  count====752538150  。。。。。超乎想象的大,看来解法一中的循环次数还是太少。

用C(52,8)计算了下,这个结果没错

概率计算结果

得到和为 56 的概率为 0.039791 ,和解法1中估算的值 0.0398 比较接近了

和为55、57的概率同为 0.039601 ,与和为 56 的概率差距真的很小了,

就这样了

[java,2018-06-26] 扑克牌抽牌求和问题的更多相关文章

  1. 2018.06.26「TJOI2018」数学计算(线段树)

    描述 小豆现在有一个数 xxx ,初始值为 111 . 小豆有 QQQ 次操作,操作有两种类型: 111 $ m$ : x=x×mx=x×mx=x×m ,输出 xxx modmodmod MMM : ...

  2. 2018.06.26 Dominator Tree--支配树

    在学习支配树之前,请保证已经会写lca(tarian求法) 简介 支配树是什么?支配树能干什么? 对于一个DAG" role="presentation" style=& ...

  3. 2018.06.26 NOIP模拟 号码(数位dp)

    题目背景 SOURCE:NOIP2015-GDZSJNZX(难) 题目描述 Mike 正在在忙碌地发着各种各样的的短信.旁边的同学 Tom 注意到,Mike 发出短信的接收方手机号码似乎都满足着特别的 ...

  4. 2018.06.26 NOIP模拟 纪念碑(线段树+扫描线)

    题解: 题目背景 SOURCE:NOIP2015−GDZSJNZXSOURCE:NOIP2015-GDZSJNZXSOURCE:NOIP2015−GDZSJNZX(难) 题目描述 2034203420 ...

  5. http://stormzhang.com/opensource/2016/06/26/android-open-source-project-recommend1/

    转载自:http://stormzhang.com/opensource/2016/06/26/android-open-source-project-recommend1/ 推荐他的所有博文~ 图片 ...

  6. 2018.10.26 浪在ACM 集训队第二次测试赛

    2018.10.26 浪在ACM 集训队第二次测试赛 整理人:苗学林 A海港 参考博客:[1]:李继朋https://www.cnblogs.com/violet-acmer/p/9859006.ht ...

  7. 用python实现一个小游戏——抽牌

    想要实现一个抽牌的功能,有很多种实现方法,这时候我们创造一个对象,通过内置方法来完成这个功能: # Author:Zhang Zhao # -*-coding:utf-8-*- from collec ...

  8. Insider Dev Tour(2018.06.28)

    时间:2018.06.28地点:北京金茂万丽酒店

  9. OPPO Developers Conference(2018.12.26)

    时间:2018.12.26地点:北京国家会议中心

随机推荐

  1. Gym101889J. Jumping frog(合数分解+环形dp预处理)

    比赛链接:传送门 题目大意: 一只青蛙在长度为N的字符串上跳跃,“R”可以跳上去,“P”不可以跳上去. 字符串是环形的,N-1和0相连. 青蛙的跳跃距离K的取值范围是[1, N-1],选定K之后不可改 ...

  2. VMware 虚拟机安装-->wrf、cmaq安装

    微信关注公众号 “软件安装管家” 下载并安装VMware 下面简要记载我的安装和设置步骤: 下载解压,右键以管理员方式运行 安装好了之后 双击桌面 的VMware 输入许可证密钥:AA510-2DF1 ...

  3. 原来你是这样的setTimeout

    先上代码 console.log("start"); setTimeout(function(){ console.log("Hello"); },200); ...

  4. 锋利的jQuery初学(3)

    jQuery详细介绍 1,$的含义:就是一个名称符号:jquery占用了两个变量:$和jquery; 2,js与jQuery的入口函数区别 (1),js的window.onload事件是等到所有内容加 ...

  5. delphi的流操作的语法

    Delphi在这两方面都做的相当出色.在Delphi的早期版本Turbo Pascal 中就曾有流(Stream).群(Collection)和资源(Resource)等专门用于对象式数据管理的类.在 ...

  6. Ubuntu使用总结二

    Ubuntu使用 - 1.ubuntu怎么切换到root用户,切换到root账号方法 ubuntu怎么切换到root用户,我们都知道使用su root命令,去切换到root权限,此时会提示输入密码, ...

  7. 【druid 】数据库连接池

    一.数据库连接池架构 二.数据库连接池的过滤器 spi的思想,加载配置文件的Filter druid.filters.default=com.alibaba.druid.filter.stat.Sta ...

  8. 关于WeakEventManger的引用

    在引用WeakEventManger时,代码里添加的命名空间是System.Windows,但项目引用的却是WindowsBase,真奇葩.

  9. vue-router 路由跳转:和name配对的是params,和path配对的是query

    1.命名路由name搭配params,刷新页面参数会丢失 2.路由path搭配query,刷新页面数据不会丢失 3.接收参数使用this.$router,就能获取到参数的值

  10. Day 16 模块和包的导入

    包的认识 包通过文件夹来管理一些列功能相近的模块 包:一系列模块的集合体 重点:包中一定有一个专门来管理包中所有模块的文件 包名:存放一系列模块的文件夹名字 包名(包对象)存放的是管理模块的那个文件地 ...