题解:学而思编程 数字谜题

【题目来源】

学而思编程:数字谜题

【题目描述】

有一个数学谜题是这样的:已知 \(1234=1\)\(5678=3\)\(6089=5\),请问 \(2571=\)

解决这个问题的诀窍在于——将等式左侧的数字看成图形,数一数各位数字包含圈的数量就是右侧的答案,具体来说:

  • 数字 \(0,4,6,9\) 中包含一个圈。
  • 数字 \(8\) 中包含两个圈。
  • 数字 \(1,2,3,5,7\) 中不含圈。

给定一个整数,请你输出它的圈数量。

【输入】

一行一个整数 \(n\)

【输出】

一行一个整数,表示整数 \(n\) 包含的圈圈数量。

【输入样例】

1234

【输出样例】

1

【核心思想】

  1. 问题分析:给定一个整数 \(n\),计算其各位数字中包含的"圈"的数量。规则为:\(0, 4, 6, 9\) 各含 \(1\) 个圈,\(8\)\(2\) 个圈,其余数字不含圈。这是一个数位分解 + 查表累加问题,关键在于将数字逐位拆分并映射到对应的圈数。

  2. 算法选择

    • 逐位分解:通过 %10/10 逐位提取数字
    • 查表映射:用函数 quan(n) 将单个数字映射为圈数
    • 线性累加:遍历所有位,累加圈数
  3. 关键步骤

    • 初始化:读取整数 \(n\)

    • sum = 0:总圈数

    • 逐位计算

      • n > 0 时循环:
        • sum += quan(n % 10):累加最低位的圈数
        • n /= 10:去掉最低位
    • 输出 sum

    • 映射函数 quan(d)

      • d == 8:返回 \(2\)
      • d == 0 || d == 4 || d == 6 || d == 9:返回 \(1\)
      • 否则:返回 \(0\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(\log n)\),与数字位数成正比
    • 空间复杂度:\(O(1)\),仅需常数变量
  5. 数位分解的核心思想

    • 十进制逐位提取n % 10 获取最低位,n /= 10 右移一位,循环直至 \(n = 0\),天然处理任意位数的整数
    • 离散映射:圈数规则是离散的,用条件判断或数组查表均可,函数封装提高可读性
    • 前导零无关:整数表示不含前导零,不影响结果(前导零若存在也贡献圈数,但标准整数输入无此问题)
    • 零值处理:输入 \(n = 0\) 时循环不执行,`sum = 0$,但 \(0\) 实际含 \(1\) 个圈,需注意边界(本题输入为正整数,可忽略)
    • 适用于"数位特征统计"类问题,逐位分解配合映射表是标准解法

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;

int n, sum;  // n: 输入的数字, sum: 总权值

// 计算单个数字的权值
int quan(int n)
{
    if (n == 8)  // 数字8的权值为2
    {
        return 2;
    }
    if (n == 0 || n == 4 || n == 6 || n == 9)  // 数字0,4,6,9的权值为1
    {
        return 1;
    }
    return 0;  // 其他数字的权值为0
}

int main()
{
    cin >> n;  // 输入数字

    // 逐位计算数字的权值
    while (n)
    {
        sum += quan(n % 10);  // 计算最低位数字的权值并累加
        n /= 10;  // 去掉最低位数字
    }

    cout << sum << endl;  // 输出总权值

    return 0;  // 程序正常结束
}

【运行结果】

1234
1
posted @ 2026-07-05 15:51  团爸讲算法  阅读(11)  评论(0)    收藏  举报