Among all the factors of a positive integer N, there may exist several consecutive numbers. For example, 630 can be factored as 3×5×6×7, where 5, 6, and 7 are the three consecutive numbers. Now given any positive N, you are supposed to find the maximum number of consecutive factors, and list the smallest sequence of the consecutive factors.
Input Specification:
Each input file contains one test case, which gives the integer N (1<N<231).
Output Specification:
For each test case, print in the first line the maximum number of consecutive factors. Then in the second line, print the smallest sequence of the consecutive factors in the format factor[1]*factor[2]*...*factor[k]
, where the factors are listed in increasing order, and 1 is NOT included.
Sample Input:
630
Sample Output:
3
5*6*7
题目分析:
简单来说,就是暴力枚举,但是是有剪枝的枚举。
首先题目是要求我们找出连续相乘的因子,由连续数相乘很容易联想到阶乘,再看题目给出的N的范围是1<N<2^31,通过计算可以得出12!<2^31<13!,所以所求的连续因子最多也就只有12个数相乘(这种情况是最小的几个连续数相乘,再往后数越大,所以相乘的连续数个数自然就减少)
所以进而只要枚举这12个数字的子序列中可能的组合,为了提高计算效率,进一步进行剪枝。考虑到是连续数相乘,则至少要有两个数,很容易就想到将N开平方,得到连续数可以取到的最大值的上界。下界就是从2开始,题目说了1不算。
从2到sqrt(N)+1,每一个数依次轮流作为连续因子的起始数,后面枚举乘上连续数,每乘一个都要判断一下是不是N的约数,如果不是就要退出,因为再往上累乘已经没有意义了。
最后还需要对质数进行判断,由于质数只有1和它本身这两个约数,而题目说在输出连续因子序列的时候1是不算的,所以只能输出本身,这种情况要单独处理。
代码如下:
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int N;
scanf("%d",&N);
int mid=sqrt(N)+1;//上界,之所以要+1,是因为取整后舍去了一部分,比如6,开根号后取整是2,显然约数3才是最大的
int sum,len=0,start=0;
int i,j;
for(i=2;i<=mid;i++)
{
sum=1;//连续因子的起始数
for(j=i;j<=mid;j++)
{
sum=sum*j;
if(N%sum!=0)break;//当前的连续因子不是数N的约数,那么无论后面再乘多少数都不会是N的约数,所以跳出
}
//上面的循环退出时有两种情况:
//1、当前的j乘上后不是N的约数了,所以是j-i>len的判断,而不是j-i+1>len的判断
//2、j=mid+1,此时的j显然也是不可取的,判断同上
if(j-i>len)
{
len=j-i;
start=i;
}
}
if(start==0)printf("%d\n%d",1,N);//一个除1和本身以外的约数都没有,即质数
else{
printf("%d\n%d",len,start);
for(int i=start+1;i<start+len;i++)
printf("*%d",i);
}
cout<<endl;
return 0;
}
运行结果如下: