LightOJ 1038 Race to 1 Again

来源:互联网 发布:化学词典软件 编辑:程序博客网 时间:2024/05/21 17:00

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25915


题意:给一个数n,每次等概率选择它的一个因子p,然后得到n/p,求变为1时的期望次数。

思路:f[i]表示从i变为1的期望次数,f[i] = 1/t ( ∑f[j] ) + 1 ( j是i的因数 )化简一下,得到 f[i] =  ( ( ∑f[j] ) + t ) / ( t-1 ) //t为所有的因子个数,包括1和本身  j为i的真因子。


#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define Clean(x,y) memset(x,y,sizeof(x))const int maxn = 100009;double f[maxn];bool flag[maxn];int p[maxn][10];int n,T;void getfactor(int x){    p[x][0] = 0;    for( int i = 2; i * i <= x; i++ )    {        if ( x % i == 0 )        {            p[x][ ++p[x][0] ] = i;            if ( i * i != x )            p[x][ ++p[x][0] ] = x / i;        }    }}double cal( int x ){    if ( flag[x] ) return f[x];    flag[x] = true;    getfactor(x);    double ans = 0;    for(int i = 1; i <= p[x][0]; i++) ans+=cal( x / p[x][i] );    return f[x] = ( ans + p[x][0] + 2 ) / ( p[x][0] + 1 );}int main(){    Clean(flag,false);    f[0] = f[1] = 0;    flag[0] = flag[1] = true;    Clean(p,0);    scanf("%d",&T);    int k = 0;    while(T--)    {        k++;        scanf("%d",&n);        printf("Case %d: %.10f\n",k,cal(n));    }    return 0;}


0 0
原创粉丝点击