当前位置: 首页 > article >正文

【C++】角谷猜想问题分析与解答


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯题目描述
  • 💯我的初始做法
    • 代码实现
    • 代码分析
  • 💯优化后的做法
    • 优化目标
    • 优化后的C++代码
    • 优化效果
  • 💯老师的做法
    • 代码实现
    • 对比分析
  • 💯总结与扩展
    • 思路总结
    • 代码优化技巧总结
    • 拓展思考
  • 💯小结

在这里插入图片描述


在这里插入图片描述


💯前言

  • 在算法学习的过程中,经典问题往往蕴含着丰富的逻辑思维训练。本文将对一道经典的编程题目——角谷猜想进行深入解析,并展示不同的解法,包括C++风格代码C语言风格代码的实现。此外,我们将详细对比代码思路,找出其差异与优化之处,并对相关概念进行拓展,让读者全面理解问题的本质及其高效解决方案
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2077 角谷猜想
在这里插入图片描述

题目名称:B2077 角谷猜想

角谷猜想(Collatz Conjecture)是一个著名的数学问题,描述如下:

  • 给定一个正整数 N N N,如果 N N N 是奇数,则执行 N = N × 3 + 1 N = N \times 3 + 1 N=N×3+1
  • 如果 N N N 是偶数,则执行 N = N / 2 N = N / 2 N=N/2
  • 重复上述过程,直到 N = 1 N = 1 N=1 为止。

输入格式
一个正整数 N ( N ≤ 2 , 000 , 000 ) N (N \leq 2,000,000) N(N2,000,000)

输出格式
从输入整数 N N N 计算到 1 1 1 的步骤,每一步输出计算过程,格式如:

5*3+1=16
16/2=8
8/2=4
4/2=2
2/2=1
End

若输入直接为 1 1 1,输出:

End

输入输出样例

输入输出
55*3+1=16
16/2=8
8/2=4
4/2=2
2/2=1
End

💯我的初始做法


代码实现

下面是我最初的C++代码实现:

#include <iostream>
using namespace std;

int main() {
    int a;
    cin >> a;
    while (a != 1) {
        if (a % 2 != 0) {
            cout << a << "*3+1=" << a * 3 + 1 << endl;
            a = a * 3 + 1;
        }
        if (a % 2 == 0) {
            cout << a << "/2=" << a / 2 << endl;
            a = a / 2;
        }
    }
    cout << "End" << endl;
    return 0;
}

在这里插入图片描述


代码分析

  1. 输入与输出:使用 cincout 进行数据输入和输出。
  2. 逻辑结构:
    • 循环条件为 a != 1,即不断执行操作直到 a = 1 a = 1 a=1
    • 判断奇偶性:
      • 如果 a % 2 ≠ 0 a \% 2 \neq 0 a%2=0(奇数),计算 a = a * 3 + 1 并输出结果;
      • 如果 a % 2 = = 0 a \% 2 == 0 a%2==0(偶数),计算 a = a / 2 并输出结果。
  3. 问题点:
    • 整数溢出:当 a a a 较大时,a * 3 + 1 可能会超出 int 的表示范围,导致程序错误或无限循环。
    • 冗余判断:两个独立的 if 语句增加了不必要的判断。

💯优化后的做法


优化目标

为了解决程序可能的 时间超时 (TLE) 和 整数溢出 问题,我进行了以下优化:

  1. 数据类型优化:将变量 int 改为 long long,以避免大数溢出;
  2. 逻辑简化:使用 if-else 避免重复判断,提高执行效率。
  3. 代码风格优化:保持简洁与高效。

优化后的C++代码

#include <iostream>
using namespace std;

int main() {
    long long a;
    cin >> a;
    while (a != 1) {
        if (a % 2 == 1) {
            cout << a << "*3+1=" << (a = a * 3 + 1) << endl;
        } else {
            cout << a << "/2=" << (a /= 2) << endl;
        }
    }
    cout << "End" << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述


优化效果

  1. 数据安全:long long 能处理更大的数值,解决了溢出问题。
  2. 高效逻辑:使用 if-else 避免冗余判断。
  3. 清晰输出:在一行中完成输出和赋值操作,简洁高效。

💯老师的做法


代码实现

老师提供了一种 C语言风格 的代码实现,具体如下:

#include <cstdio>

int main() {
    long long n = 0;
    scanf("%lld", &n);
    while (n != 1) {
        if (n % 2 == 1) {
            printf("%lld*3+1=%lld\n", n, n * 3 + 1);
            n = n * 3 + 1;
        } else {
            printf("%lld/2=%lld\n", n, n / 2);
            n /= 2;
        }
    }
    printf("End\n");
    return 0;
}

在这里插入图片描述
在这里插入图片描述


对比分析

  1. 输入输出:
    • 老师使用 scanfprintf,这是 C语言 的输入输出方式,效率较高。
    • 我的代码使用 cincout,这更符合现代C++的编程习惯,但效率稍低。
  2. 数据类型:
    • 老师同样使用了 long long,解决了溢出问题。
  3. 逻辑结构:
    • 老师通过 if-else 避免了冗余判断。
    • 在一行中完成输出和赋值操作,使代码更为简洁。
  4. 效率:
    • C语言的 printfscanf 相对于 coutcin 更快,适合数据量大的场景。

💯总结与扩展


思路总结

  1. 角谷猜想的逻辑:
    • 奇数: a = a × 3 + 1 a = a \times 3 + 1 a=a×3+1
    • 偶数: a = a / 2 a = a / 2 a=a/2
  2. 数据类型的重要性:
    • 处理大数时,选择合适的数据类型(如 long long)非常关键。
  3. 高效输入输出:
    • printfscanfcoutcin 更快,适用于对性能要求高的场景。
  4. 逻辑简化:
    • 避免冗余判断,使用 if-else 提高代码效率。

代码优化技巧总结

  • 减少冗余判断:使用 if-else 避免多次判断。
  • 合并操作:输出和赋值可以在一行中完成,简化代码结构。
  • 选择合适的数据类型:特别是在处理大数时,避免溢出。
  • 输入输出优化:使用 printfscanf 代替 coutcin 提高效率。

拓展思考

  • Collatz猜想的性质:
    角谷猜想虽然简单,但至今没有数学证明。无论输入什么正整数,最终都会收敛到 1,这也是该猜想的有趣之处。
  • 时间复杂度:
    每次操作会将偶数减半,执行次数大致为 O ( log ⁡ N ) O(\log N) O(logN)
  • 算法训练意义:
    本题锻炼了对 循环控制、条件判断 和 数据处理 的综合能力,是学习算法的良好入门题目。

💯小结

  • 在这里插入图片描述
    通过对角谷猜想问题的深入解析,我们了解了如何高效地解决该问题,并对C++风格C风格的代码进行了对比。优化程序的核心在于选择合适的数据类型、优化逻辑结构以及提高输入输出的性能。这道题不仅帮助我们理解基础的循环与判断结构,也让我们体会到在不同编程风格下性能的差异。

在这里插入图片描述



http://www.kler.cn/a/447002.html

相关文章:

  • 熟悉u8g2图形库C语言函数
  • 国标GB28181协议平台Liveweb:搭建建筑工地无线视频联网监控系统方案
  • maven-resources-production:ratel-fast: java.lang.IndexOutOfBoundsException
  • SpringBoot开发——整合JSONPath解析JSON信息
  • 2024年合肥师范学院信息安全小组内部选拔赛(c211)WP
  • 虚拟机断网没有网络,需清理内存,删除后再重启
  • 基于Java Web的“使用Ajax实现无刷新实时显示公告信息”实验
  • Spring实例化的基本流程和Bean处理器
  • LeetCode 2545.根据第 K 场考试的分数排序:考察编程语言的排序
  • 现代 CSS 布局与响应式设计实战指南
  • asp.net多媒体教室管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目
  • 使用Mac自带共享实现远程操作
  • TANGO与LabVIEW控制系统集成
  • [ESP]从零开始的Arduino IDE安装与ESP环境配置教程
  • HBase、Hive、Redis 和 MongoDB的对比
  • C语言的函数指针
  • linux-----文件命令
  • Latex 转换为 Word(使用GrindEQ )(英文转中文,毕业论文)
  • AdminJS - 集成 MySQL 的现代化管理面板开发指南
  • CSS3 实现火焰-小火苗效果
  • linux中大内核锁、互斥锁、信号量、完成变量、自旋锁区别
  • 【AIGC-ChatGPT进阶提示词-《动图生成》】怪物工厂:融合想象力与创造力的奇幻世界
  • vscode 使用说明
  • 四川托普信息技术职业学院教案1
  • 智能挂号系统设计典范:SSM 结合 Vue 在医院的应用实现
  • Windows下安装Rabbit MQ