CCCC/GPLT L1-006 连续因子

题目重现

一个正整数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

题解

直接从2开始枚举连续因子序列的起点即可。

由于是连续的,只需要记录连续因子序列的起点与终点即可。

product(start,end)=i=startendi

根据题意要求:

product(start,end)|N

符合要求的 start, end 有若干对,要求出其中长度(end - start)最长,其次起点(start)最小

answerCandidates.reduce((pre, cur) => {
    if (cur.end - cur.start > pre.end - pre.start) return cur;
    if (cur.end - cur.start < pre.end - pre.start) return pre;
    if (cur.start < pre.start) return cur;
    return pre;
}, {
    start: N,
    end: N
});

这种将多个元素转化成一个元素的抽象做法称为 Reduce,典型的例子有:求和、求最值、状态更新等。
特征是“有损的信息聚合”。

性能

  • 枚举连续因子序列起点 start[2,N] ,如果使用 [2,N] 将会直接超时,因为N很大。
  • start 开始迭代终点 end ,碰到第一个不能整除的就结束迭代,此时 end 不能计入答案序列,因此是左开右闭区间
  • 迭代过程中,要拷贝一个N,每次迭代用 end 除它,不需要在每次迭代中计算一个连续积。

时间复杂度: O(NFactorial1(N))

Factorial 是阶乘函数,其反函数在 [2,231) 上的值域为 [2,12] 可以近似看成常数。

需要注意的测试样例

2147483647

INT_MAX,有上溢的危险。

至少有3种方法可以解决这个问题:

  1. 可以使用long long
  2. 加特殊判断
  3. 使用闭区间描述起点、终点

但总的来说,使用闭区间很难保证程序简洁易懂。

在计算机程序中,我们经常使用左闭右开区间去描述一个序列。

代码示例

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值