http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2862

晕 多加了一个# wa了N久  细节呀

代码及其注释:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<stack>
#include<vector>
#include<algorithm>
#include<queue>

#define ull unsigned long long
#define ll long long
#define lint long long
using namespace std;

const double eps=1e-12;
const int INF=0x3f3f3f3f;
const int N=1000010;
double dp[N];//记忆化搜索数组
int p[N];//标记是否是素数
int prime[N];//将素数从小到大放到prime数组里面
double dfs(int x)
{
    if(dp[x]>=-0.5)
    return dp[x];//记忆化
    if(x==1)//边界
    return (dp[x]=0.0);
    double sum=0.0;
    int p=0,g=0;//p表示所有小于等于x的素数个数 g表示这些素数中是x的约数的个数
    for(p=0;prime[p]<=x;++p)//枚举所以小于等于x的素数
    if(x%prime[p]==0)
    {
        ++g;
        sum+=dfs(x/prime[p]);
    }
    return (dp[x]=(sum+p)/g);//这个式子推导可得
}
int main()
{
    //freopen("data.in","r",stdin);
    memset(p,-1,sizeof(p));
    int ln=0;
    for(int i=2;i<N;++i)
    {
        if(p[i])
        {
            prime[ln++]=i;
            for(int j=i+i;j<N;j+=i)
            {
                p[j]=0;
            }
        }
    }
    for(int i=0;i<N;++i) dp[i]=-1.0;
    int T;
    scanf("%d",&T);
    for(int c=1;c<=T;++c)
    {
        int n;
        scanf("%d",&n);
        printf("Case %d: %.10lf\n",c,dfs(n));
    }
    return 0;
}

 

posted on 2013-07-12 17:17  夜->  阅读(175)  评论(0编辑  收藏  举报