Project Euler problem 323

Topic Link

At first glance this question is bit computing, in fact, a probability distribution and related topics.

There y0 y1 y2 series 32bits unsigned number
x is initially 0, then the series and the number of exclusive-or operation, the operation N times, until x is 2 ^ 32-1, in fact, all bits are 1 x.
N demand expectations.

How to calculate expectations?
For each n is calculated corresponding to the probability p (n), then the weighted sum.
We now look one by one analysis
N is 1, then that y0 every bits are 1, the probability is 1 / (2 ^ 32)
N 2, were calculated for each bit, the first bit, the result is the probability that 1 minus the probability is not 1, the probability is not 1 is the first bit is not 0, the first bit y0 y1 is not 0, the probability is 1 / (2 ^ 2), then p (2) = (1-1 / (2 ^ 2)) ^ 32 - P (. 1)
N is 3, p (3) = ( 1-1 / (2 ^ 3)) ^ 32 - p (1) - p (2)
so
topic after ten decimal required, if the p (n) is small, the results are not affected by multiplying n, that is, p (n) * 10 ^ n is less than ten.

When I do a calculation of the probability of a data structure stored in the numerator and denominator. After the answer I came out, looked at the analysis of others, feel the direct use double to save the probability can give the correct answer, I did not try, uncertain.
Here is my code:

      
      
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
      
      
public class
{
public BigInteger Numerator { get; set; }
public BigInteger Denominator { get; set; }
public (BigInteger numerator, BigInteger denominator)
{
Numerator = numerator;
Denominator = denominator;
}
Big Box   Euler Project 323 title = "line">}
public static string GetAnswer()
{
List<Probability> probabilities = new List<Probability>();
probabilities.Add( new Probability( 0, 1));
BigInteger twoPow32 = BigInteger.Pow( 2, 32);
for ( int i = 1; ; i++)
{
BigInteger baseDenominator = BigInteger.Pow( 2, i);
BigInteger baseNumerator = baseDenominator - 1;
BigInteger lastBaseDenominator = BigInteger.Pow( 2, i - 1);
BigInteger lastBaseNumerator = lastBaseDenominator - 1;
BigInteger denominator = BigInteger.Pow(baseDenominator, 32);
BigInteger numerator = BigInteger.Pow(baseNumerator, 32);
BigInteger lastNumerator = BigInteger.Pow(lastBaseNumerator, 32);
probabilities.Add( new Probability(
numerator - lastNumerator * twoPow32,
denominator));
if (probabilities[i].Denominator / probabilities[i].Numerator / i > BigInteger.Pow( 10, 12))
{
break;
}
}
BigInteger ansDenominator = probabilities.Last().Denominator;
BigInteger ansNumerator = 0;
for ( int i = 1; i < probabilities.Count; i++)
{
Probability current = probabilities[i];
BigInteger times = ansDenominator / current.Denominator;
ansNumerator += times * current.Numerator * i;
}
BigInteger times11 = ansNumerator * 100000000000 / ansDenominator;
double answer = ( double)times11 / 100000000000;
return answer.ToString( "N10");
}

Guess you like

Origin www.cnblogs.com/lijianming180/p/12302572.html
Recommended