(数学,概率论)Card Trick

Card Trick
Time Limit: 3000ms, Special Time Limit:7500ms, Memory Limit:65536KB
Total submit users: 11, Accepted users: 11
Problem 12949 : Special judge
Problem description

Input

For each test case:

• A line containing two integers n (1 ≤ n ≤ 100) and m (1 ≤ m ≤ 10) where n is the number of selected cards and m is the 1-based position of my first selected card.

• A line with n tokens that specify the n selected card faces (in order, including the final card). Each card face is given either as an integer x (2 ≤ x ≤ 10) or as a single character (J, Q, K, or A as specified above).

Output

For each test case, print one line containing the probability that Alice chooses a starting position that leads to the same final card. Your output should have an absolute error of at most 10^−7.

Sample Input
5 2
2 3 5 3 Q
1 1
A
1 2
A
1 10
A
6 1
2 2 2 2 2 2
7 1
2 2 2 2 2 2 2
3 10
10 J K
Sample Output
0.4871377757023325348071573
0.1000000000000000000000000
0.1000000000000000000000000
0.1748923357025314239697490
0.5830713210321767445117468
0.6279229611115749556280350
0.3346565827603272001891974
Problem Source
NWERC 2013

//比赛当时只有一位同学做了,佩服。
//链接:http ://acm.hnu.cn/online/?action=problem&type=show&id=12949&courseid=280
//题意:给定n个数和初始位置,根据公式求出xi + 1 = xi + c(i)计算出最后一个位置(J,Q,K当10,A当11),求从前十个位置任意选一个 ,到达相同位置的概率。
//思路:先根据给定的数据求出左后的位置,然后倒着推概率,将概率相加,除以10即为所求,其中已经到过的位置,到达最终位置的概率为1,其他的则有(2 - 11,用j表示,其中10有四张牌)九种可能性,
//每一种位置i的概率是i*j(j取所有值)的概率的平均值。
//代码:
 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
const int maxn = 2005;
double p[maxn], ans;
int n, m;
int main()
{
	char s[maxn];
	int t;
	while (scanf("%d%d", &n, &m) != EOF)
	{
		memset(p, 0, sizeof(p));
		int start = m;
		for (int i = 1; i <= n; i++)
		{
			scanf("%s", s);
			p[start] = 1;
			if (s[0]<'A'&&s[0] >= '2'&&s[0] <= '9')
				t = s[0] - '0';
			else if (s[0] == '1' || s[0] == 'J' || s[0] == 'Q' || s[0] == 'K')
				t = 10;
			else
				t = 11;
			start += t;
		}
		ans = 0;
		for (int i = start; i >= 1; i--)
		{
			if (p[i] == 0)
			{
				for (int j = 2; j <= 11; j++)
				{
					t = (j == 10 ? 4 : 1);
					p[i] += t*p[i + j];
				}
				p[i] = p[i] / 13;
			}
			if (i <= 10)
				ans += p[i];
		}
		printf("%.16f\n", ans / 10);
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值