LightOJ - 1038

Rimi learned a new thing about integers, which is - any positive integer greater than 1 can be divided by its divisors. So, he is now playing with this property. He selects a number N. And he calls this D.

In each turn he randomly chooses a divisor of D (1 to D). Then he divides D by the number to obtain new D. He repeats this procedure until D becomes 1. What is the expected number of moves required for N to become 1.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case begins with an integer N (1 ≤ N ≤ 105).

Output

For each case of input you have to print the case number and the expected value. Errors less than 10-6 will be ignored.

Sample Input

3

1

2

50

Sample Output

Case 1: 0

Case 2: 2.00

Case 3: 3.0333333333

大概题意:

选择1-D中可以被D整除的数字,然后用D出得到一个新的数字D1;

然后在找所有D1的因子,用D1除,直到得到1,问除的次数的期望值;

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;


const int maxn = 1e5+5;
double dp[maxn];

void work()
{
	memset(dp, 0, sizeof dp);
	dp[1] = 0;
	dp[2] = 2;
	for(int i = 3; i <= maxn; i++)	
	{	
		double sum = 0;
		int c = 0;
		for(int j = 1; j * j <= i;  j++)
		{
			if(i % j == 0)  
            {  
                sum += dp[j];  
                c++;  
                if(j*j != i)  
                {  
                    sum += dp[i/j];  
                    c++;  
                }  
            } 	 
		}
		dp[i] = 1.0*(sum + c)/(c - 1); 
           //d[i] = ( d[1] + d[a2] + d[a3] + d[a4] ..... + d[i] + c) / c , a2, z3 ...为 i 的约数
	}
}

int main()
{
	int t;
	scanf("%d", &t);
	
      work(); 
for(int i = 1; i <= t; i++){int n ;scanf("%d", &n);int sum = 0;printf("Case %d: %.6lf\n", i, dp[n]);}return 0; }

猜你喜欢

转载自blog.csdn.net/qq_38295645/article/details/80468414