题目:
一个正整数 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
大体思路:
先判断是不是素数,不是的话,找出所有的因数,如果连续的话,开始计数,如果计数到有因子使得之前和自己本身之积不能除以N,计数清零,从开始计数的第二个数开始计数(如1441440的因数有1,2,3,4,5,6,7,8等,但是不能同时被他们整除,所有第一种情况从1开始计数,第二种情况从3开始计数,以此类推)。如果不是因数,计数也清零。注意每次清零要保存较大的数字。
这道题本来我是想:
比如630=2*3*3*5*7,然后2,3是连续因子;5,2*3,7是连续因子,这里的6可以用比5小的数字相乘来判断是否能得到。但是有很多漏洞,比如当要两个数字相乘的时候是在一组连续因子的第一个数字,不好求。
后来纠正:1.先判断是不是质数。2.可以先把所有因子都找出来(不要以为一个数字只能用一次),来判断哪一组因子最长。
//我想如果没有数组如何储存最大的因子序列?但是没有数组的话可以存储一个数:即开始的数字,然后用for循环就好了
//看了CSDN上面定义数字用的是long long型的,结果运行超时,可以用unsigned int
//然后我有发现理解错了题目,以为只要找出因子就可以了,结果发现因子之积还要能整除N
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int isprime(int n);
int main()
{
unsigned int N,N1;
scanf("%d",&N);
unsigned int i;
unsigned int s=0,temp;
unsigned int max=0,start;
if(isprime(N))
printf("1\n%d\n",N);//如果是素数,直接输出本身
else
{
N1=N;
for(i=2;i<=N/2;i++)
{
if(N%i==0 && N1%i==0)//如果是连续并且能整除N的因子
{
N1=N1/i;
s=s+1;
if(i==N/2)
{
if(max<s)
{
temp=s;
max=temp;
start=i-temp+1;
}//如果因子是最大的数字,s直接和前面最长的s比较
}
}
else if(N%i==0 && N1%i!=0)//如果是因子,但是已经不能整除N了的情况
{
N1=N;
if(max<s)
{
temp=s;
max=temp;
start=i-temp;
}
i=i-s+1;//上一段从初始的i开始计数,这一段从i+1开始计数,比如上一段从2开始,这一段从3开始。
s=1;//s不为0
continue;
}
else//不是因子
{
N1=N;
if(max<s)
{
temp=s;
max=temp;
start=i-temp;
}//在s归零之前,比较一下s和之前最长的s
s=0;//不是因子,s直接归零,等到下一段再开始计算
}
}
printf("%d\n",max);
for(i=start;i<start+max-1;i++)
printf("%d*",i);
printf("%d",start+max-1);
}
return 0;
}
int isprime(int n)
{
int i;
for(i=2;i<=sqrt(n);i++)
{
if(n%i==0)
return 0;
}
return 1;
}