• LightOJ 1341 Aladdin and the Flying Carpet(整数拆分定理)


      分析:题目并不难理解,就是一些细节上的优化需要我们注意,我在没有优化前跑了2000多MS,优化了一些细节后就是400多MS了,之前还TLE了好几次。

      方法:将整数拆分为质因子以后,表达为这样的形式,e1*p1 + e2*p2 + .... + en*pn,整数的所有约数的个数为(1+p1)*(1+p2)*(1+pn);

      注意:当时我也在担心,题目中要求我们的分解成的两个数不能相等,但是当我们求出约数总数以后直接除了2(因为我们只需要一半),没有特殊处理相等的情况,会不会出错? 其实不会,我们这个是整除2,巧妙的把中间的约数挖去了,举个例子吧,4的约数有(1,2,4)三个,这里能用的只有(1,4)这一组,3/2 = 1,正好是正确答案。这里是一个细节,应该注意到。

      具体的一些细节表示在下面的代码里:

      

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    #define LL long long///数据比较强,建议LL
    #define maxn 1000010///质因子,所有sqrt(1^12) = 1^6就够了
    LL is_prime[maxn],prime[maxn],cnt;
    void make_prime()
    {
        memset(is_prime,1,sizeof(is_prime));
        is_prime[1] = 0;
        cnt = 0;
        for(int i = 2; i <= maxn; i++)
        {
            if(is_prime[i])
            {
                prime[cnt++] = i;///建议在这就记数
                for(int j = 2*i; j <= maxn; j += i)
                    is_prime[j] = 0;
            }
        }
    }
    LL slove(LL num)
    {
        LL sum = 1;
        for(int i = 0; i < cnt && prime[i]*prime[i] <= num; i++)///质因子一定满足平方小于等于原数
        {
            ///尽量使用乘积的形式,这里不会溢出,而根号有精度或者其他问题,当时我开了根号居然是超时……
            int tot = 0;
            if(num == 1) break;///及时退出
            while(num % prime[i] == 0)
            {
                num /= prime[i];
                tot++;
            }
            sum *= (tot+1);
        }
        if(num > 1) sum *= 2;
        return sum;
    }
    int main()
    {
        int t,ca = 0;
        LL a,b;
        make_prime();
        scanf("%d",&t);
        while(t--)
        {
            scanf("%lld%lld",&a,&b);
            if(a < b*b)///注意这个小小的判断,它会节省很多时间。
            {
                printf("Case %d: 0
    ",++ca);
                continue;
            }
            LL num = slove(a);
            num /= 2; /// 整除
            for(LL i = 1; i < b; i++)///我们还要去掉不满足的解
            {
                if(a % i == 0) num--;
            }
            printf("Case %d: %lld
    ",++ca,num);
        }
        return 0;
    }
  • 相关阅读:
    寒假自学1.11
    寒假学习1.10
    寒假自学1.09
    寒假自学1.08-python的安装学习
    寒假1.08
    寒假自学1.07
    寒假自学1.06-tensorflow安装过程
    java & | 运算符
    java << >>
    java基础百位数十位数个位数
  • 原文地址:https://www.cnblogs.com/jifahu/p/5585219.html
Copyright © 2020-2023  润新知