L1-006 连续因子(分数20)

题目描述

一个正整数N,可以被拆分为几个连续因子相乘,比如630可以分解为3×4×5×6,其中4×5×6就是它的一个连续因子序列。

题目要求

给一个正整数N(不超过int范围),求出它的最长的连续因子序列,第一行输出该序列的长度,第二行以“a×b×...×m”的格式输出(不包含双引号)


解题思路

分析可知,每一个连续因子序列都能被N整除,所以我们可以枚举每一个开头i,利用双指针j,看j最远能走到哪。

1. 使用一个temp变量存储乘积,初始值为1。使用一个len记录最大长度,初始为0。还需要一个first记录连续因子序列的开头

2. j从i开始,temp不断乘j,j不断右移,当temp不能被N整除时,就断了,最大的序列长度为 j - i

这里的计算过程是:因为j多加了一个1,所以j-1,又因为长度 = 终点坐标 - 起点坐标 + 1 , 所以(j-1) - i + 1 = j - i;

3. 如果j-i大于len,就更新len,同时更新first。

最后 枚举结束后,由于first不一定会更新,所以需要讨论first情况

*如果first没有更新,为原始值0,说明N最长只有一个连续因子,且为它本身,比如质数。
*否则,从first输出,这里可以将长度看成偏移量,first+0 , ... ,first + len - 1 ,当然还需要注意输出格式

即时提问:枚举i需要从1枚举到n吗?为什么代码中枚举的范围是 1 到 sqrt(n)?

#include<iostream>
#include<cmath>
using namespace std;
int main()
{
	int n;
	cin>>n;
	long long len = 0 , first = 0 ;
	int maxn = sqrt(n);
    //从起始因子开始枚举
	for(int i = 2 ; i <= maxn ; i++)
	{
		int j ;
		long long temp = 1;
		for(j = i ;;j++)
		{
			temp *= j;
			if(n % temp != 0) break;
		}
		if((j-1) - i + 1 > len)
		{
			len = j - i;
			first = i;
		}
	}
    //如果起始因子从未更新,说明不存在,只有它自己
	if(first == 0) cout<<"1"<<endl<<n;
	else 
	{
		cout<<len<<endl;
		for(int i = 0 ; i< len ; i++)
		{
			cout<<first + i ;//按偏移量输出
			if(i != len - 1) cout<<"*";
		}
	}
	return 0;
}
posted @ 2026-03-09 10:58  shuiwangrenjia  阅读(1)  评论(0)    收藏  举报