67. 两个闲玩娱乐

1.扑克牌的顺子

从扑克牌中随机抽5 张牌,判断是不是一个顺子,即这5 张牌是不是连续的。2-10 为数字本身,A 为1,J 为11,Q 为12,K 为13,而大小王可以看成任意数字。


HANDWRITING:

大小王当0,5张牌排好序

bool straight (int poker[]) {
	int jokers = 0, i;
	for (i = 0; poker[i] == 0; ++i) ++jokers;
	int start = poker[i];
	for(; i < 5; ++i) {
		if (poker[i] == start) ++start;
		else if (jokers > 0) --jokers;
		else return false;
	}
	return true;
}

1、没有考虑到当ooker[i] != start时,i不能向后移

改正:

bool straight (int poker[]) {
	int jokers = 0, i;
	for (i = 0; poker[i] == 0; ++i) ++jokers;
	int start = poker[i];
	while (i < 5) {
		if (poker[i] == start) ++start, ++i;
		else if (jokers > 0) --jokers, ++start;
		else return false;
	}
	return true;
}



2.n 个骰子的点数。

把n 个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S 的所有可能的值出现的概率。


HANDWRITING:

计算出各个S出现的次数,概率即S[ i ] / 6^N

void dice (int n) {
	int *s = new int[6 * n + 1];
	for (int i = 1; i <= 6; ++i) s[i] = 1;
	for (int c = 2; c <= n; ++c) {
		for (int d = c * d; d >= c ; --d) {
			s[d] = s[d-1] + s[d-2] + s[d-3] + s[d-4] + s[d-5] + s[d-6];
		}
	}
	for (int i = 1; i <= 6 * n; ++i) cout<<s[i]<<" ";
	cout<<endl;
}

1、没考虑d-6是否大于0

2、没释放new出来的空间

改正:

void dice (int n) {
	int *s = new int[6 * n + 1];
	for (int i = 1; i <= 6; ++i) s[i] = 1;
	for (int c = 2; c <= n; ++c) {
		for (int d = c * 6; d >= c ; --d) {
			for (int i = 1; i < d && i <= 6; ++i)
				s[d] += s[d - i];
		}
	}
	for (int i = 1; i <= 6 * n; ++i) cout<<s[i]<<" ";
	cout<<endl;
	delete [] s;
}

ANSWER:

FROM:http://blog.csdn.net/v_july_v/article/details/6870251
All the possible values includes n to 6n. All the event number is 6^n.
For n<=S<=6n, the number of events is f(S, n)
f(S,n) = f(S-6, n-1) + f(S-5, n-1) + … + f(S-1, n-1)
number of events that all dices are 1s is only 1, and thus f(k, k) = 1, f(1-6, 1) = 1, f(x, 1)=0 where x<1 or x>6, f(m, n)=0 where m<n 
Can do it in DP.

void listAllProbabilities(int n) {
  int[][] f = new int[6*n+1][];
  for (int i=0; i<=6*n; i++) {
    f[i] = new int[n+1];
  }
  for (int i=1; i<=6; i++) {
    f[i][1] = 1;
  }
  for (int i=1; i<=n; i++) {
    f[i][i] = 1;
  }
  for (int i=2; i<=n; i++) {
    for (int j=i+1; j<=6*i; j++) {
      for (int k=(j-6<i-1)?i-1:j-6; k<j-1; k++)
        f[j][i] += f[k][i-1];
    }
  }
  double p6 = Math.power(6, n);
  for (int i=n; i<=6*n; i++) {
    System.out.println(“P(S=”+i+”)=”+((double)f[i][n] / p6));
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值