PTA天梯赛 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

解析:

这道题我们有个需要注意的地方

  1. 答案要求输出最长连续因子序列
  2. 若有两个相同长度的连续因子序列,要求输出最小的连续因子序列
  3. 还有一个隐含条件就是题目给出的例子是630=3×5×6×7,也就是说你的连续因子序列的乘积也要整除N。
  4. 1不算在内
    于是,我就开始了我的想法,若要找到因子,那么总体上可分为两种情况:
    一种是N为质数:
    那么最后输出的序列只能是N本身;
    那么我们只需从2到根号下N来不断整除N
    若能够整除
    再判断是否是连续的因子,若是连续因子则更新当前序列长度及序列最后一个因子的值并将i累乘到current(要保证current不大于N),若不是连续因子则仅更新current为i
    若不能够整除则不做任何操作
    然后再判断当前序列长度是否大于当前最长序列,若大于则更新当前最长序列
    最后输出结果
//我首次提交的代码如下(C++)
#include<iostream>
using namespace std;
int main()
{
	// 虽然这道题最大数据在2^31,但是实际测试数据用int不够
    long int N,current=1,time=1,last=0,maxtime=1,maxlast=0;
    cin >> N; 
    for(int i=2;current*i<=N;i++){
    	// 判断i是否为连续因子,1不算在内
        if(N%i==0&&N%(i-1)==0&&i!=2){
        	//current记录当前连续因子序列乘积,但没有加判断 
            current*=i;
            // 遇到连续因子更新序列长度 
            time++; 
            // 更新当前序列最后一个因子
            last=i; 
        }
        else{
        	// 若不是连续因子则current重置为i
            current=i;
            //序列长度重置为1 
            time=1; 
            if(N%i==0)
            	// 更新当前子序列最后一个因子
                last=i;         
            }
        // 更新当前最长子序列长度
        if(maxtime<time){ 
            maxtime=time; 
            // 这一步判断其实duck不必
            if(maxlast<last) 
                maxlast=last;
        }
    }
    cout << maxtime << endl;
    // 加一步判断num是否为质数
    cout << (maxtime==1?N:maxlast-maxtime+1); 
    for(int i=maxlast-maxtime+2;i<=maxlast;i++)
        cout << '*' << i;
    return 0;
}

错误发现

  1. 对于60这一测试数据,忽视了最长连续子序列长度仍为N的因子,因此最长子序列不是2×3×4而是3×4×5
  2. 对于899这一测试数据,其因子为1、29、31、899,其最长连续因子应为29,若用上述代码提交由于maxtime初始化即为1,因此即使找到29,time置为1也不会更新maxtime,会将其当作质数进行输出

问题解决

#include<iostream>
using namespace std;
int main()
{
    unsigned int N; // 也可以用long int
    cin >> N;
    // 该解法中定义的变量意义与上面的错误解法想同,但这里将maxtime和maxlast的初始化值都定义为了1就可以解决在根号下N范围内只有一个因子的情况
    unsigned int current=1,last=0,time=0,maxlast=0,maxtime=0;
    for(unsigned int i=2;i*i<=N;i++){
    	// 在这里较上面的解法做出了简化,易知若i和i-1是满足题目条件的因子那么他们的乘积一定能整除N
        if(N%(i*(i-1))==0&&i!=2){ 
        	// 这里加入了对current的判断,只有当current是N的因子时才可更新下面这三个变量的值
            if(N%(current*i)==0){ 
                current*=i;
                last=i;
                time++;
            }
        }else{
        	// 如果N可被i整除则记录i,否则不做任何操作
            if(N%i==0){
                current=i;
                // 注意此时对于899=28*31这样的数据,maxtime为0,因此可以更新maxtime和maxlast的值
                time=1;
                last=i;
            }
        }
        if(maxtime<time)
        {
            maxtime=time;
            maxlast=last;
        }
    }
    // 对于质数的处理
    if(maxtime==0){
        maxtime=1;
        maxlast=N;
    }
    cout << maxtime << endl << maxlast-maxtime+1;
    for(unsigned int i=2;i<=maxtime;i++)
        cout << "*" << maxlast-maxtime+i;
    return 0;
}

注:

此外还有一种双重循环不断找未出现的连续因子的方法,代码比我的更加简洁,大家可以去学习一下。
链接:柳婼のblog L1-006. 连续因子-PAT团体程序设计天梯赛

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这道题要求我们找出一个正整数 n 的因子最长的连续数字个数,并输出最小的连续因子序列。我们可以先将 n 分解质因数,然后找出其连续因子。 具体做法是,我们可以从最小的质因数开始,依次判断它是否是 n 的因子,如果是,则将它和后面的质因数一起乘起来,看是否还是 n 的因子,如果是,则继续乘下去,直到不是 n 的因子为止。这样就可以找到一个连续因子序列。 我们可以用一个数组来存储连续因子序列,每次找到一个更长的连续因子序列时,就更新数组。最后输出数组的最小连续因子序列即可。 下面是一个示例代码: ### 回答2: 首先,我们需要先对给定的正整数n进行因数分解,可以将其分解为质因数的乘积。然后,我们可以通过枚举所有的因子,并对每个因子判断是否连续,最终找出最长的连续因子序列。 具体的方法如下: 1. 对正整数n进行质因数分解,将其表示为p1^k1 * p2^k2 * ... * pn^kn 2. 枚举所有的因子,我们可以从2开始枚举到sqrt(n),对于每个因子i,判断是否是n的因子,若是,则计算连续因子个数。 3. 对于每个因子i,我们可以通过对i逐个加1,判断i+1是否也是n的因子,若是,则连续因子个数加1,继续判断i+2是否是因子,直到不连续为止。 4. 记录下最长的连续因子序列。 最后,输出最长的连续因子个数和最小的连续因子序列。 以下是Python实现代码: ```python import math from collections import deque def factorization(n): factors = [] i = 2 while n > 1: while n % i == 0: factors.append(i) n = n // i i += 1 if i * i > n: if n > 1: factors.append(n) break return factors def find_consecutive_factors(n): factors = factorization(n) max_len = 0 max_seq = [] for i in range(len(factors)): seq = deque([factors[i]]) for j in range(i+1, len(factors)): if factors[j] == seq[-1] + 1: seq.append(factors[j]) elif factors[j] == seq[-1]: continue else: if len(seq) > max_len: max_len = len(seq) max_seq = list(seq) break if len(seq) > max_len: max_len = len(seq) max_seq = list(seq) return max_len, max_seq if __name__ == '__main__': n = int(input("请输入正整数n:")) len, seq = find_consecutive_factors(n) print("最长的连续因子个数为:", len) print("最小的连续因子序列为:", seq) ``` 输入正整数n后,程序将输出最长的连续因子个数和最小的连续因子序列。 ### 回答3: 首先,我们可以将正整数 n 分解质因数,并将其连续因子记录下来。比如对于正整数 630,其分解式为 3 × 5 × 6 × 7,我们可以将其的 5、6、7 记录下来,得到连续因子序列 5-6-7,长度为 3。 接着,我们需要遍历正整数 n 的所有因子,找出最长的连续因子序列及其长度。具体步骤如下: 1. 首先,将正整数 n 分解质因数,得到质因数和它们出现的次数。 2. 对于每个质因数,我们可以得到它所有的因子。比如对于质因数 2,其所有因子为 1、2、4、8、16、……,其连续因子序列为 1-2、2-4、4-8、8-16、……。我们可以枚举每个因子,看其是否属于连续因子序列,并记录下来连续因子序列的长度。 3. 最后,找出最长的连续因子序列及其长度,并输出最小的连续因子序列。 核心代码如下: ```python n = int(input()) if n == 1: print(1) else: # 分解质因数 factors = [] i = 2 while i * i <= n: if n % i == 0: factors.append(i) n //= i else: i += 1 if n != 1: factors.append(n) # 枚举所有因子 max_len = 0 for f in factors: temp = [f] for i in range(factors.count(f) - 1): temp.append(temp[-1] * f) if temp[-1] == temp[0] + len(temp) - 1 and len(temp) > max_len: max_len = len(temp) start = temp[0] if max_len == 0: print(1) else: print(max_len) print('-'.join(str(start + i) for i in range(max_len))) ``` 值得注意的是,当输入的正整数为 1 时,其最长连续因子序列长度为 1,因为因子只有 1。因此,需要特判此情况。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值