329 Prime Frog
一只懂质数的青蛙站在编号为 1-500 的方块内,它等概率的向左或者向右跳,当然不能出 1-500 这些方块,如果到达了边缘就只能向另外一个方向跳。
如果方块的编号是质数,那么有 2/3 的概率呱出 P
(PRIME),1/3 的概率呱出 N
(NOT PRIME);反之如果编号不是质数,那么呱出 P
和 N
的概率分别是 1/3 和 2/3。
如果它从随机的一点出发(等概率),发出 PPPPNNPPPNPPNPN
的概率是多少呢?使用最简分数给出答案。
使用一个 List
放一系列数值对,每一对表示概率的分子和分母。从 1-500 个编号出发,将每种情况的概率存起来。
var probabilities = new List<(long, long)>();
for (int i = 1; i <= 500; i++)
{
GetProbabilityAt(i, probabilities);
}
private void GetProbabilityAt(int i, List<(long, long)> p)
{
GetProbabilityAt(i, 0, 1, 1, p);
}
private void GetProbabilityAt(int i, int step, long numerator, long denominator, List<(long, long)> result)
{
var (n, d) = GetProbabilityWithCroak(i, croaks[step]);
numerator *= n;
denominator *= d;
step++;
if (step == croaks.Length)
{
result.Add((numerator, denominator));
return;
}
if (i == 1)
{
GetProbabilityAt(i + 1, step, numerator, denominator, result);
return;
}
if (i == 500)
{
GetProbabilityAt(i - 1, step, numerator, denominator, result);
return;
}
GetProbabilityAt(i + 1, step, numerator, denominator * 2, result);
GetProbabilityAt(i - 1, step, numerator, denominator * 2, result);
}
GetProbabilityWithCroak
计算达到每一个方块对应的概率,根据题意
private static (long, long) GetProbabilityWithCroak(int i, char p)
{
if (p == 'P')
{
if (primes[i] != 0)
{
return (2, 3);
}
else
{
return (1, 3);
}
}
else
{
if (primes[i] != 0)
{
return (1, 3);
}
else
{
return (2, 3);
}
}
}
var commonD = (long)Math.Pow(6, 15);
long numerator = 0;
foreach (var pair in probabilities)
{
numerator += pair.Item1 * commonD / pair.Item2;
}
for
循环了 500 次,所以分母还要乘以 500;二是分子分母同除最大公约数化简。