天天看点

acm专题学习之数学(一)分解质因数+URAL - 2102

题目:数字N(1e18),其分解后(N=a1^p1*a2^p2...),问幂的和(p1+p2+p3...)是否为20。

思路:

  • 暴力+优化:通过观察1e6*1e6*2^18>2e18,会发现最多只有一个大于1e6的因子,那么可以只求1e6范围内的质因子,然后如果过了1e6后和的数量还为19,那么只需要判断除后剩下的是不是质数。
  • 分解质因子+优化:套用分解质因子模板,在后面不可能再有20的范围进行判断做个剪枝。

分解质因数:

原理:唯一分解定理,任何一个大于1的自然数n都可以唯一分解成有限个质数的乘积,n=p1^a1 * p2^a2 * ... * pn^a3,其中p1<p2<...<pn均为质数,它们的指数均为正整数。所以这道题分解出来的质数是可以确定的。

求质因子模板代码:

//cnt记录素数的个数,a数组从小到大记录素数
int cnt = 0;
for(int i = 2; i*i <= n; i ++)
{
    while(n % i == 0)
    {
        a[cnt ++] = i;
        n /= i;
    }
}
           

代码:

#include <algorithm>
#include <string>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int main()
{
    long long int n;
    scanf("%lld",&n);
    int cnt = 0;
    int flag=0;
    for(long long int i = 2; i*i <= n; i ++)
    {
        while(n % i == 0)
        {
            cnt++;
            n /= i;
        }
        if(cnt>20){
            break;
        }
        if(pow(i+1,20-cnt)>n){
            flag=1;
            break;
        }
    }
    if(n!=1)cnt++;
    if(cnt==20&&!flag){
        printf("Yes\n");
    }
    else {
        printf("No\n");
    }
    return 0;
}
           

注意的地方:只用分解质因子会超时,还要剪一下枝优化一下。

总结:太惨了,不会分解质因子,还看错题意,和别人差了两道题。所以平时说要多学习,技多不压身。