zoukankan      html  css  js  c++  java
  • SCNUACM新生赛解题报告-1006水题

    水题

    Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)

    Total Submission(s) : 425   Accepted Submission(s) : 7

    Problem Description

    对于正整数 n, 定义函数 f(n) 为 n 的因子之和,例:f(4)=1+2+4=7.
    对于正整数 n, 定义函数 g(n) 为 f(k) 之和,其中 k 为 n 的因子,例:g(4)=f(1)+f(2)+f(4)=1+3+7=11.
    对于正整数 n, 定义函数 h(n) 为 g(n) 的阶乘的位数,例:g(4)=11, 11! = 39916800, 故 h(4)=8.
    现在,你的任务是:对于给定的正整数 n, 求 h(n).

    Input

    多测试用例!
    每行包括一个正整数 n, 1<=n<=500000.

    Output

    每行包括一个正整数 h(n).

    Sample Input

    1

    2

    3

    4

    5

    Sample Output

    1

    2

    3

    8

    4

    Author

    SCNU20102200088

    Source

    SCNUACM

    水题不水啊,这题算是比较有难度的题目之一,对于新生来说。

    我的思路并不是太难,就是保存所有算过的f和g的值。算位数的时候用的是斯特林公式。代码写得比较难看= =。

    #include <cstdio>
    #include <string.h>
    #include <math.h>
    
    const int size = 500000 + 10;
    int save[size];//f(x)
    int g[size];//g(x)
    const double PI = acos(-1.0);//PI的精确值
    
    //计算g(a)的值,保存所有算过的f和g值
    void isPrime(int a)
    {
        int mid = sqrt(a) + 1, i, div;
        int sum = 1 + a;
        g[a] = save[1];
        for(i = 2; i < mid; i++)
        {
            if(a % i == 0)
            {
                div = a / i;
                //这里用了一些技巧
                //当对一个数x进行因式分解的时候,总是存在两个数a, b
                //a, b均小于等于根号x
                //且a * b == x
                //这里,i和div就是a和b
                if(div != i)
                {//
                    sum += div + i;
                    if(save[div] == 0) isPrime(div);
                    if(save[i] == 0) isPrime(i);
                    g[a] += save[div] + save[i];
                }
                else
                {//这是a != b的情况,即不存在一个整数a的平方等于数x
                    sum += i;
                    if(save[i] == 0) isPrime(i);
                    g[a] += save[i];
                }
            }
        }
        save[a] = sum;
        g[a] += sum;
        //printf("%d:%d
    ", a, g[a]);
    }
    
    int main()
    {
        int a, len;
        memset(save, 0, sizeof(save));
        memset(g, 0, sizeof(g));
        //save数组储存的是f(x)的值
        save[1] = 1;
        save[2] = 3;
        //g数组储存的是g(x)的值
        g[1] = 1;
        g[2] = 4;
        //for(i = 2; i < size; i++) isPrime(i);
        mr = 0;
        while(~scanf("%d", &a))
        {
            //g[a] == 0意味着g还没有被算过
            if(g[a] == 0) isPrime(a);
            a = g[a];
            //斯特林公式,计算某个数的阶乘的位数
            len = ceil((a*log((double)a)-a+log(2.0*(double)a*PI)/2.0)/log(10.0));
            //斯特林公式对len=1的情况不感冒
            if(len == 0) len = 1;
            printf("%d
    ", len);
        }
        return 0;
    }
  • 相关阅读:
    PHP实现无限极分类
    html2canvas生成并下载图片
    一次线上问题引发的过程回顾和思考,以更换两台服务器结束
    Intellij IDEA启动项目报Command line is too long. Shorten command line for XXXApplication or also for
    mq 消费消息 与发送消息传参问题
    idea 创建不了 java 文件
    Java switch 中如何使用枚举?
    Collections排序
    在idea 设置 git 的用户名
    mongodb添加字段和创建自增主键
  • 原文地址:https://www.cnblogs.com/conanliu/p/scnuacm2013_fresh_1006.html
Copyright © 2011-2022 走看看