最长连续因子问题 - C语言学习笔记

一、学习目标

  1. 理解"最长连续因子"问题的核心解法,掌握因子判断连续序列遍历的逻辑;
  2. 学会优化循环遍历范围(利用平方根减少计算量);
  3. 识别并修正代码中的语法/逻辑错误,提升代码健壮性。

二、核心知识点铺垫

1. 因子定义

若整数 a % b == 0b ≠ 1),则称 ba 的因子。

例如:60的因子有2、3、4、5、6、10等(1不算因子)。

2. 连续因子

指一组依次连续 的整数,且每个数都是目标数的因子。

例如:60的最长连续因子是 2 3 4 5 6

3. 遍历优化思路

连续因子的起始数无需遍历到 n,只需遍历到 √n

  • 若起始数 i > √n,则 i * (i+1) > n(两个连续数的乘积已超过n),无法形成长度≥2的连续因子;
  • 此优化可大幅减少循环次数,提升程序效率。

三、原代码分析(标注问题)

c 复制代码
#include <stdio.h>
#include <math.h>

int main() {
    int n;
    // 输入目标整数
    scanf("%d", &n);
    int max_len=0;  // 记录最长连续因子的长度
    int start=n;    // 记录最长连续因子的起始数
    // 外层循环:遍历所有可能的起始因子(优化到√n)
    for(int i=2;i<=sqrt(n);i++)//找连续因子在平方根的范围里判断
    {
        int temp=n;     // 临时保存n,避免修改原数
        int len=0;      // 记录当前连续因子的长度
        int current=i;  // 当前判断的因子(从起始数i开始)
        // 【错误1】中文括号")",编译报错;【错误2】缺少temp /= current,逻辑错误
        while(temp%current==0)//通过循环,来找最长的长度
        {
            len++;
            current++;
        }
        // 更新最长连续因子的起始数和长度
        if(len>max_len)
        {
            start=i;
            max_len=len;
        }
    }
    // 输出最长连续因子
    for(int i=0;i<max_len;i++)
    {
        printf("%d ",start+i);  // 【错误3】最后一个数后多一个空格,格式不规范
    }
    return 0;
}

原代码核心问题总结

错误类型 具体问题 影响
语法错误 while(temp%current==0) 中是中文右括号 编译失败,无法运行
逻辑错误 缺少 temp /= current 无法正确判断"连续因子"(temp始终是原数n,导致判断结果错误)
边界错误 未处理"质数"情况(如输入7,max_len=0,无输出) 质数无连续因子时,应输出自身,原代码无输出
格式错误 输出最后多一个空格 不符合题目输出规范

四、修正后的完整代码(带详细注释)

c 复制代码
#include <stdio.h>
#include <math.h>

int main() {
    int n;
    // 1. 输入目标整数
    scanf("%d", &n);
    
    // 初始化变量:
    int max_len = 0;    // 记录最长连续因子的长度(初始为0)
    int start = n;      // 记录最长连续因子的起始数(默认n,处理质数情况)
    
    // 2. 外层循环:遍历所有可能的起始因子(优化到√n)
    for (int i = 2; i <= sqrt(n); i++) {
        int temp = n;   // 临时变量:保存n的副本,避免修改原数
        int len = 0;    // 临时变量:记录当前连续因子的长度
        int current = i;// 临时变量:当前判断的因子(从i开始)
        
        // 3. 内层循环:判断从current开始的连续数是否都是temp的因子
        while (temp % current == 0) { // 中文括号修正为英文)
            len++;                  // 连续长度+1
            temp /= current;        // 核心修正:temp除以当前因子,继续判断下一个数
            current++;              // 下一个连续数
        }
        
        // 4. 更新最长连续因子的信息
        if (len > max_len) {
            start = i;      // 更新起始数
            max_len = len;  // 更新最长长度
        }
    }
    
    // 5. 输出结果:
    for (int i = 0; i < max_len; i++) {
        printf("%d", start + i);  // 先输出数字
        if (i != max_len - 1) {   // 最后一个数不输出空格
            printf(" ");
        }
    }
    // 处理质数(无连续因子):输出自身
    if (max_len == 0) {
        printf("%d", n);
    }
    
    return 0;
}

五、代码逐行详解

1. 头文件

c 复制代码
#include <stdio.h>  // 输入输出函数(scanf/printf)
#include <math.h>   // 数学函数(sqrt求平方根)

2. 输入与变量初始化

c 复制代码
int n;
scanf("%d", &n);          // 读取输入的整数n
int max_len = 0;          // 最长连续因子长度,初始为0
int start = n;            // 最长连续因子起始数,默认n(应对质数)

3. 外层循环(遍历起始因子)

c 复制代码
for (int i = 2; i <= sqrt(n); i++) {
    int temp = n;   // 临时保存n,避免修改原数
    int len = 0;    // 当前连续因子长度
    int current = i;// 当前判断的因子(从i开始)
    // ... 内层循环 ...
}
  • 起始数从2开始(1不算因子);
  • 终止条件i <= sqrt(n):优化遍历范围,减少计算量。

4. 内层循环(判断连续因子)

c 复制代码
while (temp % current == 0) {
    len++;                  // 连续长度+1
    temp /= current;        // 关键:temp除以当前因子,确保下一个数是剩余数的因子
    current++;              // 检查下一个连续数
}
  • 例:n=60,i=2时:
    • temp=60,current=2 → 60%2==0 → len=1,temp=30,current=3;
    • temp=30,current=3 → 30%3==0 → len=2,temp=10,current=4;
    • temp=10,current=4 → 10%4≠0 → 循环结束(原代码因缺少temp/=current,会错误判断到current=7)。

5. 更新最长序列

c 复制代码
if (len > max_len) {
    start = i;
    max_len = len;
}
  • 若当前连续长度超过已记录的最长长度,更新起始数和最长长度。

6. 输出结果

c 复制代码
for (int i = 0; i < max_len; i++) {
    printf("%d", start + i);
    if (i != max_len - 1) {
        printf(" ");
    }
}
if (max_len == 0) {  // 质数无连续因子,输出自身
    printf("%d", n);
}
  • 循环输出从start开始的max_len个连续数;
  • 最后一个数不输出空格,符合格式要求;
  • 质数(max_len=0)时,输出自身。

六、示例演示(输入60)

执行过程关键步骤:

  1. 输入n=60,max_len=0,start=60;
  2. 外层循环i=2:
    • temp=60,current=2 → 60%2==0 → len=1,temp=30,current=3;
    • temp=30%3==0 → len=2,temp=10,current=4;
    • temp=10%4≠0 → 循环结束,len=2 > max_len(0) → start=2,max_len=2;
  3. 外层循环i=3:
    • temp=60%3==0 → len=1,temp=20,current=4;
    • temp=20%4==0 → len=2,temp=5,current=5;
    • temp=5%5==0 → len=3,temp=1,current=6;
    • temp=1%6≠0 → len=3 > max_len(2) → start=3,max_len=3;
  4. 继续遍历到i=√60≈7,最终找到最长序列起始数2,长度5;
  5. 输出:2 3 4 5 6。

七、关键注意事项

  1. 语法细节:编程时需区分中英文符号(括号、分号、逗号等),中文符号会导致编译错误;
  2. 逻辑核心temp /= current 是判断连续因子的关键,若缺少此步,无法正确缩小判断范围;
  3. 边界处理:必须考虑"质数"的特殊情况(无连续因子,输出自身);
  4. 格式规范:输出时避免最后一个数后多空格,符合题目要求。

八、总结

  1. 最长连续因子问题的核心是双层循环:外层遍历起始因子(优化到√n),内层判断连续因子;
  2. 关键逻辑:通过temp /= current 确保连续数都是剩余数的因子;
  3. 易错点:中文符号、缺少核心赋值、未处理质数边界、输出格式不规范。
相关推荐
Genevieve_xiao2 小时前
【写给新人】在 vscode 中配置适用于算法竞赛背景的 c/c++
c语言·vscode·算法
YmaxU2 小时前
SpringAIAlibaba学习使用 ---Graph
java·学习·spring·ai
Be for thing2 小时前
Android 屏幕硬件原理 + 显示驱动与功耗优化实战(手机 / 手表通用)
android·学习·智能手机
朗迹 - 张伟2 小时前
UE5 Road Creator Pro 插件学习笔记
笔记·学习·ue5
暴躁小师兄数据学院2 小时前
【WEB3.0零基础转行笔记】Go编程篇-第11讲:Gin框架
笔记·golang·web3·区块链·智能合约
wincheshe2 小时前
AI Agent 开发学习 --- 构建软件团队智能体(二)
人工智能·学习
雷工笔记2 小时前
小笔记|常读常新
笔记
Mr.Cheng.2 小时前
【InternVL2-2B】MLLM内部架构学习笔记
笔记·学习·自然语言处理
悠哉悠哉愿意3 小时前
【物联网学习笔记】串口接收
笔记·单片机·嵌入式硬件·物联网·学习