题目描述
样例
输入
3 2155895064 3 2 2 10000000000 10
输出
2238728 1 10000000000
基本思路
-
首先,要找出构成n的所有素因子,这些因子满足两个条件:是素数(函数判断),且能被n或n的中间值整除(用取余%);
-
其次,要循环除去满足条件的素因子,用while做,取余做结束判断,同时记录对同一素因子除法执行的次数
-
第三,判断次数是否大于等于k,满足的乘到结果变量ans上(所以对每个n,ans要初始化为1)
-
最后,输出ans的结果
80到100分的关键点在剪枝:
-
最重要的剪枝,代码里也写了,就是对10^10量级的数来说,倒数2个素因子的数值普遍相差比较大,如果一直循环走,就会无效地消磨时间,造成超时,所以,如果对n处理后发现剩的是一个素数了(素数的多次方不是素数),那么就到了如例题所说处理完23接着发现剩107的情况了,就不用从24到107找素数了,直接就剩107,幂次为1,直接和k判断大小进行取舍操作
-
还有一个剪枝就是处理完成之后,如果n==1了,那么证明处理完成了,直接到下一个n即可
代码
#include<bits/stdc++.h>
using namespace std;
bool isSu(long long n) //判断n是否是素数
{for(long long i=2;i<n;i++){if(n%i==0) return false; //表示除了1和本身还有其他的因子}return true;
}
int main()
{int q;cin>>q;long long n,k;long long ans=1;for(int i=0;i<q;i++){cin>>n>>k;int count=0;ans=1;if(isSu(n)) //这部分可有可无,对剪枝作用不大{if(k==1) cout<<n<<endl;else cout<<"1"<<endl;continue;}for(int j=2;j<n;j++){if(isSu(n)&&k==1) //!!!最重要的剪枝过程,80到100的突破点(从例题中发现,23到107还要无效循环很多次,这里又是普遍存在的现象,把这块剪掉){ans*=n;break;}else if(isSu(n)) break;count=0;if(isSu(j)&&(n%j==0)) //判断:是素数并且是n的因子{while(n%j==0&&n!=1){n/=j;count++;}if(count>=k) {ans*=pow(j,count);}}if(n==1) break; }cout<<ans<<endl;}return 0;
}
提交结果
任何问题欢迎留言,也欢迎大家分享自己的思路,谢谢!点赞收藏不迷路哦~