使用C语言求解扑克牌的顺子及n个骰子的点数问题

扑克牌的顺子
    问题描述:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。
         思路:可以将这5张牌排个序,然后统计出0的个数以及非0数字之间的间隔数,如果出现重复的非0数字,那么不是顺子。如果间隔数小于等于0的个数,那么是顺子。暂时未想到更好的办法。
         参考代码:

//函数功能 : 从扑克牌中随机抽5张牌,判断是不是一个顺子
//函数参数 : pCards为牌,nLen为牌的张数
//返回值 : 是否顺子
bool IsContinuous(int *pCards, int nLen)
{
 if(pCards == NULL || nLen <= 0)
  return false; 

 sort(pCards, pCards + nLen); //调用标准库的排序算法 

 int i;
 int zeroCount = 0; //大小王用0表示
 int capCount = 0; //间隔数
 //统计0的个数
 for(i = 0; i < nLen; i++)
 {
  if(pCards[i] == 0)
   zeroCount++;
  else
   break;
 }
 //统计间隔数
 int preCard = pCards[i];
 for(i = i + 1; i < nLen; i++)
 {
  int curCard = pCards[i];
  if(preCard == curCard) //与前一张牌比较
   return false;
  else
   capCount += curCard - preCard - 1; //累加间隔数
  preCard = curCard;
 }
 return (zeroCount >= capCount)? true: false; //只要王的个数大于间隔数
}

n个骰子的点数
问题描述:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。
         思路:这是一道应用动态规划思想的题目,而动态规划最难的就是要找最优子结构。并采取一种称为备忘录的方法避免重复计算。因为备忘录方法为每个解过的子问题建立了备忘录,以备需要时参看,避免了相同子问题的重复求解。
        本题的最优子结构为:F(k, n) 表示k个骰子点数和为n的种数,k表示骰子个数,n表示k个骰子的点数和

     /  = F(k-1, n-6) + F(k-1, n-5) + F(k-1, n-4) + F(k-1, n-3) + F(k-1, n-2) + F(k-1, n-1)  对于 k > 0, k <= n <= 6*k
 F(k, n) =
     \  = 0    对于 n < k or n > 6*k

当k=1时, F(1,1)=F(1,2)=F(1,3)=F(1,4)=F(1,5)=F(1,6)=1。
         从上面公式可以看出,k个骰子点数和为n的种数只与k-1个骰子的和有关。这就可以用到备忘录的方法,用一张表格保存已解决的子问题的解,然后自底向上填表。考虑到当前层的计算只与下一层有关,因此只需保存一行。
         参考代码:

const int FACE_NUM = 6; //骰子的面数 

//函数功能 : n个骰子的点数
//函数参数 : number为骰子数
//返回值 : 无
void PrintSumProbabilityOfDices(int number)
{
 if(number <= 0)
  return; 

 int *pSum = new int[number * FACE_NUM + 1]; //和的种类
 double total = pow(6.0, number); //<cmath>
 int size = number * FACE_NUM;
 int i,j,k; 

 //初始化
 pSum[0] = 0;
 for(i = 1; i <= FACE_NUM; i++)
  pSum[i] = 1;
 for(; i <= size; i++)
  pSum[i] = 0; 

 for(i = 2; i <= number; i++) //骰子个数从2到n
 {
  for(j = i * FACE_NUM; j >= i; j--) //第i个骰子的和的范围为 [i, i*FACE_NUM]
  {
   pSum[j] = 0;
   for(k = 1; k <= 6 && j >= k; k++) //其实展开就是 F(i, j) = F(i-1, j-6) + F(i-1, j-5) + F(i-1, j-4) + F(i-1, j-3) + F(i-1, j-2) + F(i-1, j-1)
   {
    pSum[j] += pSum[j-k];
   }
  }
  //不可能的情况,即i个骰子的和不可能小于i
  for(j = i - 1;j >= 0; j--)
   pSum[j] = 0;
 } 

 //打印结果
 for(i = 0; i <= size; i++)
  cout<<"sum = "<<i<<", p = "<<pSum[i] / total<<endl;
}
(0)

相关推荐

  • js计算德州扑克牌面值的方法

    本文实例讲述了js计算德州扑克牌面值的方法.分享给大家供大家参考.具体如下: 1. 代码如下: 复制代码 代码如下: var Poker = function(n){     this.num = (n % 13) + 2;     this.ch = this.num > 9 ? ("abcdef"[this.num-10]) : this.num;     this.show = "0,1,2,3,4,5,6,7,8,9,10,J,Q,K,A".split

  • C++德州扑克的核心规则算法

    自己编写,适用于windows,linux平台. #include "public.h" int TexasCombine5(unsigned char* pCard, unsigned char* pCardColor, unsigned char** pCardResult, unsigned char** pColorResult) { int count = 0; //这里为了速度,没用求组合的公式 if (pCard[6] == 0)//6张牌 { count = 6; *p

  • 纯CSS实现扑克牌效果

    这也能用CSS来实现啊!为了演示方便,这里用JavaScript代码去控制了扑克牌的切换,挺不错的. Playing Cards with CSS3! body { background: #DDDDDD; overflow: hidden; } body .fire { color: #FF0000; } p { background: #FFFFFF; border: 1px solid #CCCCCC; border-radius: 5px 5px; -moz-border-radius:

  • javascript实例--教你实现扑克牌洗牌功能

    我们一般都会按照顺序把随机摸过来的牌从小到大的顺序在手上理整齐(记得小时候打牌两副牌手都抓不过来),这篇随笔就是想通过实现这个功能来熟悉下js中排序数组等相关知识. 用到知识点: 1.工厂方式创建对象 2.js数组sort()方法 复制代码 代码如下: var testArr = [1, 3, 4, 2];     testArr.sort(function (a,b) {         return a - b;     })     alert(testArr.toString());//

  • 【算法】扑克发牌算法实现

    首先给扑克牌中每张牌设定一个编号,下面算法实现的编号规则如下: u 红桃按照从小到大依次为:1-13 u 方块按照从小到大依次为:14-26 u 黑桃按照从小到大依次为:27-39 u 梅花按照从小到大依次为:40-52 u 小王为53,大王为54 算法实现如下: u 首先按照以上编号规则初始化一个包含108个数字的数组 u 每次随机从该数组中抽取一个数字,分配给保存玩家数据的数组 实现该功能的代码如下所示: 复制代码 代码如下: import java.util.*; /** * 发牌算法的实

  • 使用C语言求解扑克牌的顺子及n个骰子的点数问题

    扑克牌的顺子     问题描述:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的.2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字.          思路:可以将这5张牌排个序,然后统计出0的个数以及非0数字之间的间隔数,如果出现重复的非0数字,那么不是顺子.如果间隔数小于等于0的个数,那么是顺子.暂时未想到更好的办法.          参考代码: //函数功能 : 从扑克牌中随机抽5张牌,判断是不是一个顺子 //函数参数 : pCards

  • Java语言求解完美数代码分析

    1.概念 首先我们理解一下,什么叫做完美数? 问题描述:若一个自然数,它所有的真因子(即除了自身以外的约数)的和恰好等于它本身,这种数叫做完全数.简称"完数" 例如, 6=1+2+3 28=1+2+4+7+14 496=1+2+4+8+16+31+62+124+248 8128=1+2+4+8+16+32+64+127+254+508+1016+2032+4064 按照完数的定义,其实用程序求解完数并不是太难,先求解出这个数的所有真因子,然后相加,判断是否等于它本身即可.但是,在这个数

  • java语言求解兔子问题代码分析

    1.思考 兔子问题,是费氏数列的形象化说法,它是由一位名为Fibonacci的数学家在它的著作中提出的一个问题. 2.描述 它体术的问题是:若有一只免子每个月生一只小免子,一个月后小免子也开始生产.起初只有一只免子,一个月后就有两只免子,二个月后有三只免子,三个月后有五只免子(小免子投入生产)...... 我们使用数学的方式表达出来,便是下面的一组数列: 1.1.2.3.5.8.13.21.34.55.89...... 注意:新生的小免子需一个月成长期才会投入生产!而且这些兔子是不死的哦!!!

  • C语言求解无向图顶点之间的所有最短路径

    本文实例为大家分享了C语言求解无向图顶点之间的所有最短路径的具体代码,供大家参考,具体内容如下 思路一: DFS,遇到终点之后进行记录 辅助存储: std::vector<int> tempPath; std::vector<std::vector<int>> totalPath; 实现: //查找无向图的所有最短路径,直接dfs就可以解决了 //记录保存这里用 vector<vector<int>> 插入失败,重新搞一下 OK // 时间复杂度

  • C语言求解定积分的方法

    本文实例为大家分享了C语言求解定积分的具体方法,供大家参考,具体内容如下 题目要求: 求下面函数的定积分: 思路: 求一个函数的定积分,其实就是求它的面积,如对函数 求积分. 也就是要求出绿色部分的面积,如下: 我们可以通过矩形的方法来无限逼近定积分的求解,如下: 因为被分成n等分,就可以认为每一等分是一个矩形,那么每一矩形的面积为: 每一个矩形面积为:***Sn=f(x)(b-a)/n 总面积为:****S=S1+S2+-+Sn 通过这样的一个思路就可以完成,定积分的求解. 这样这三个定积分的

  • 用C语言求解一元二次方程的简单实现

    目录 C语言 求解一元二次方程 求一元二次方程的解,考虑所有情况 1.a = 0 2.a != 0 C语言 求解一元二次方程 在用C语言求解一元二次方程的时候,首先,最重要的肯定是要引入"math.h"这个头文件,其次要会运用相关的数学库函数,如“sqrt”,“delta”等. 让我们一起在代码中寻找问题吧. #include <stdio.h> #include <math.h> int main (void) {     int a = 1,b = 2,c

  • C语言求解最长公共子字符串问题及相关的算法分析

    题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串.注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中.请编写一个函数,输入两个字符串,求它们的最长公共子序列,并打印出最长公共子序列. 例如:输入两个字符串BDCABA和ABCBDAB,字符串BCBA和BDAB都是是它们的最长公共子序列,则输出它们的长度4,并打印任意一个子序列. 分析:求最长公共子序列(Longest Common Subsequence, LCS)是一道非常经典的

  • C语言实现扑克牌计算24点

    题目描述: 一副扑克牌的每张牌表示一个数(J.Q.K分别表示11.12.13,两个司令都表示6).任取4张牌,即得到4个1~13的数,请添加运算符(规定为加+ 减- 乘* 除/ 四种)使之成为一个运算式.每个数只能参与一次运算,4个数顺序可以任意组合,4个运算符任意取3个且可以重复取.运算遵从一定优先级别,可加括号控制,最终使运算结果为24.请输出一种解决方案的表达式,用括号表示运算优先.如果没有一种解决方案,则输出-1表示无解. 输入格式说明: 输入在一行中给出4个整数,每个整数取值在[1,

  • 用C语言求解第N项斐波那契数列问题

    目录 求解第N项斐波那契数列 求解斐波那契数列的前n项并输出及兔子繁殖问题 斐波那契数列的定义 算法思路 代码实现 兔子繁殖问题 求解第N项斐波那契数列 斐波那契数列指的是这样一个数列:1,1,2,3,5,8,13,21,34,55,89... 这个数列从第3项开始,每一项都等于前两项之和.斐波那契数列,又称黄金分割数列,显然它又是一个线性递推数列,由数学家莱昂纳多·斐波纳契首次引入此概念.在现代的物理,化学,生物等诸多领域,皆有重大影响. 在此求解过程中,我用了if 语句和for循环.话不多说

  • C语言实现求解最小公倍数的算法示例

    目录 题目描述 问题分析 方法一:穷举法 方法二:定理法 题目描述 求任意两个正整数的最小公倍数 问题分析 两个或多个整数公有的倍数叫做它们的公倍数,其中除0以外最小的一个公倍数就叫做这几个整数的最小公倍数.整数a,b的最小公倍数记为[a,b],同样的,a,b,c的最小公倍数记为[a,b,c],多个整数的最小公倍数也有同样的记号. .与最小公倍数相对应的概念是最大公约数,a,b的最大公约数记为(a,b).关于最小公倍数与最大公约数,我们有这样的定理:(a,b)x[a,b]=ab(a,b均为整数)

随机推荐