题目:数字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;
}
注意的地方:只用分解质因子会超时,还要剪一下枝优化一下。
总结:太惨了,不会分解质因子,还看错题意,和别人差了两道题。所以平时说要多学习,技多不压身。