连续因子
一个正整数 N 的因子中可能存在若干连续的数字。例如 630 可以分解为 3×5×6×7,其中 5、6、7 就是 3 个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。
输入格式:
输入在一行中给出一个正整数 N(1<N<231)。
输出格式:
首先在第 1 行输出最长连续因子的个数;然后在第 2 行中按 因子1×因子2×……×因子k 的格式输出最小的连续因子序列,其中因子按递增顺序输出,1 不算在内。
输入样例:
630
输出样例:
3
5*6*7
Talk is cheap. Show me the code.
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int main()
{
int n=0;
cin>>n;
vector<int> factors;
for(int i=2;i<=sqrt(n);i++)
{
int temp=1;
vector<int> temp_f;
for(int j=i;temp<=n;j++)
{
temp=temp*j;
if(n%temp==0)
{
temp_f.push_back(j);
if(temp_f.size()>factors.size())
{
factors.assign(temp_f.begin(),temp_f.end());
}
}
else
{
break;
}
}
}
if(factors.size()==0)
{
cout<<1<<endl;
cout<<n<<endl;
}
else
{
cout<<factors.size()<<endl;
for(int i=0;i<factors.size();i++)
{
cout<<factors[i];
if(i!=factors.size()-1)
{
cout<<"*";
}
}
}
}
解题思路
看到输入格式就下意识的联想到就一个数是否为素数的题,所以外循环中就用了sqrt()函数以防运行超时,后从网上得知平方后是不会有连续因子的,侧面也提示了我们数学知识很重要。言归正传,我们知道素数是没有因子的,所以只用输出它自己即可,长度便是1啦。对于合数来说,这道题的题目描述有可能会误导我们,我们并不需要求出正好的分解因子,例如:630 = 3 × 5 × 6 × 7,但是我们并不需要求出这4个因子,630平方以内的非1因子有2 3 5 6 7 9 10 14 15 18 21,而这些因子的乘积也必定能够被630整除,所以内循环中我们从2开始计算630%2==0可知2是因子存入vector中,630%(2×3)==0可知3也是因子也存入vector中,而630%(2×3×4)!=0可知4不是因子所以不存入vector中则break,这算一次循环,记录每次循环得到的vector的长度,如果下一次循环的vector的长度大于上一次循环的我们就进行覆盖即可。每次内循环直到乘积小于等于输入N就必须停止(因为因子乘积不可能大于N),但实际上应该也是很难到达,因为遇到不整除的乘积还是挺容易的。
分步代码解读
1.
int n=0;
cin>>n;
vector<int> factors;
for(int i=2;i<=sqrt(n);i++)
{
int temp=1;
vector<int> temp_f;
for(int j=i;temp<=n;j++)
{
temp=temp*j;
if(n%temp==0)
{
temp_f.push_back(j);
if(temp_f.size()>factors.size())
{
factors.assign(temp_f.begin(),temp_f.end());
}
}
else
{
break;
}
}
}
我们不可能一次就求得最大乘积,所以得用两层循环,外层从2开始至sqrt(N)即可停止,内层循环是求连续的因子,内层和外层肯定会重复但是并不影响,例如:外层从2开始,内层已经求得2和3都是因子,但是遇到非因子4结束时,外层仍要从3开始进入下一层内循环,但是连续因子的长度肯定是小于上次循环的(例如:上次循环的连续因子为2 3,而下次的为3,遇到4即停止了)。注意:找到更长的连续因子从而覆盖上一层时需要用assign()而不能用swap(),因为swap()是交换两个vector中的元素,而原本factors中的长度肯定是小于存着新找到的更长的连续因子的temp_f中的,会导致不能完整输出连续因子,会少一位。
2.
if(factors.size()==0)
{
cout<<1<<endl;
cout<<n<<endl;
}
else
{
cout<<factors.size()<<endl;
for(int i=0;i<factors.size();i++)
{
cout<<factors[i];
if(i!=factors.size()-1)
{
cout<<"*";
}
}
}
如果是素数直接输出长度1的本身即可,合数的话则根据vector的长度进行输出即可,注意最后一个*需要控制不能输出,否则会出现格式错误。