一個正整數N的因子中可能存在若干連續的數字。例如630可以分解為356*7,其中5、6、7就是3個連續的數字。給定任一正整數N,要求編寫程序求出最長連續因子的個數,並輸出最小的連續因子序列。
輸入格式:
輸入在一行中給出一個正整數N(1<N<2的31次方)。
輸出格式:
首先在第1行輸出最長連續因子的個數;然后在第2行中按“因子1因子2……*因子k”的格式輸出最小的連續因子序列,其中因子按遞增順序輸出,1不算在內。
輸入樣例:
630
輸出樣例:
3
567
分析:
根據N的值的取值范圍小於等於2的31次方,而這個值介於12的階乘到13的階乘之間,所以我們可以得到最大的值應該是12個數連續相乘,又因為1不計算在內,所以最多只要有11為連續因子即可。
采用暴力的思想,我們讓他分別從2、3、4...sqrt(N)開始乘,連着乘11位、10位...1位。
即連續乘11位時分別為:
2 3 4 5 6 7 8 9 10 11 12相乘
3 4 5 6 7 8 9 10 11 12 13相乘
...
連續乘10位時分別為:
2 3 4 5 6 7 8 9 10 11相乘
3 4 5 6 7 8 9 10 11 12相乘
...
一直到只有一位相乘時,
這其中只要找的一個乘積s,使得N%s==0,我呢么即可認為找到了連續因子。因為iwomen這樣找的規律就是符合題目上的先從長度最大的開始找,然后相同長度的里面又從開始的因子小的開始。
為了優化代碼,我們可以在每次乘的時候如果當前的乘積已經大於N了,就沒有再往下乘的必要了
代碼:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
int main()
{
int N;
scanf("%d",&N);
int n=sqrt(N);
int i,j;
long long int sum;
for(int len=11;len>=1;len--)//len控制連續因子的個數,由於N范圍的限制最多只能到12的階乘
{
for( i=2;i<=n;i++)//連續因子不包括1,從2開始乘,最大乘到N開方就肯定夠了
{
sum=1;
for( j=i;j<=len-1+i;j++)//從當前的i開始,乘以的個數為len的長度
{
sum*=j;
if(sum>N)//到這就沒有必要往下算了
break;
}
if(N%sum==0)//當前的sum值是N的一個因子
{
printf("%d\n%d",len,i);
for(int k=i+1;k<j;k++)
printf("*%d",k);
printf("\n");
return 0;
}
}
}
printf("1\n%d\n",N);//質數的情況
return 0;
}