CCF CSP 202312-2因子化简
题目描述
样例
输入
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;
}
提交结果
任何问题欢迎留言,也欢迎大家分享自己的思路,谢谢!点赞收藏不迷路哦~
原文地址:https://blog.csdn.net/qq_63349644/article/details/135939271
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!