原题记录:
对于给定的字符序列,从左至右将所有的数字字符取出拼接成一个无符号整数(字符序列长度小于100,拼接出的整数小于2^31,),计算并输出该整数的最大素因子(如果是素数,则其最大因子为自身)
- 首先什么是某个数a的素因子?
当数i能够整除a且i为素数,那么i就是数a的素因子,最大素因子就是取所有a的素因子中的最大值
实现
- 穷举法
最简单粗暴的办法就是穷举,i从a开始自减1,每次判断是否能够整除a并且是素数,找到的第一个i就是最大的。
缺点:这种办法效率很低,并且数越大,判断素数的循环次数就越多,对于大数,肯定会超时的
- 初步改进
每一个数都可以分为n个数的乘积形式(n未知)。由此我们可以把数a中的因子逐步剔除。
从i=2开始,先将2的所有倍数从a中剔除,若a=x*2n,则剔除2的倍数后,a=x,然后i=3,4,···,a-1,依次进行。当然,能够剔除的前提是,a能够整除i,即a%i=0。最后a一定是一个没有因子的素数了,且a一定是最大的,因为凡是小于a的因子都被剔除了。这就是我们要找的最大素因子。
- 进一步改进
但其实上述方法还有改进的空间,随着剔除的进行,a值会越来越小,实际上当i>sqrt(a)时,凡是小于i的数都被剔除了,因此a不会含有因子i,(即a= x*i,x<i不存在)所以i的循环可以在sqrt(a)时终止。此时的a已经是最大的素因子。
题解代码:
#include <iostream>
#include <cstring>
#include <math.h>
using namespace std;
unsigned int getNum(string str){
unsigned int num=0;
int len=str.length();
for(int i=0;i<len;i++)
{
if(str[i]>='0' && str[i]<='9')
{
unsigned int temp=str[i]-'0';
num = num*10 + temp;
}
}
return num;
}
unsigned int getMaxPrimeFactor(unsigned int num){
for(int i=2;i*i<=num;i++)
{
while(num%i == 0){
num=num/i;
}
}
return num;
}
int main()
{
int n;
cin>>n;
string str[n];
for(int i=0;i<n;i++)
{
cin>>str[i];
}
unsigned int num=0;
unsigned int pf=0;
for(int i=0;i<n;i++)//对每一个字符串处理
{
//先取数字
num = getNum(str[i]);
if (num == 0)//没有数字或找出的数为0
{
cout<<0<<endl;
continue;//继续下一个字符串的处理
}
//再判断最大素因子
pf = getMaxPrimeFactor(num);
cout<<pf<<endl;
}
return 0;
}
以上为个人做题笔记,仅作参考