题解:学而思编程 数字谜题
【题目来源】
学而思编程:数字谜题
【题目描述】
有一个数学谜题是这样的:已知 \(1234=1\),\(5678=3\),\(6089=5\),请问 \(2571=\) ?
解决这个问题的诀窍在于——将等式左侧的数字看成图形,数一数各位数字包含圈的数量就是右侧的答案,具体来说:
- 数字 \(0,4,6,9\) 中包含一个圈。
- 数字 \(8\) 中包含两个圈。
- 数字 \(1,2,3,5,7\) 中不含圈。
给定一个整数,请你输出它的圈数量。
【输入】
一行一个整数 \(n\)。
【输出】
一行一个整数,表示整数 \(n\) 包含的圈圈数量。
【输入样例】
1234
【输出样例】
1
【核心思想】
-
问题分析:给定一个整数 \(n\),计算其各位数字中包含的"圈"的数量。规则为:\(0, 4, 6, 9\) 各含 \(1\) 个圈,\(8\) 含 \(2\) 个圈,其余数字不含圈。这是一个数位分解 + 查表累加问题,关键在于将数字逐位拆分并映射到对应的圈数。
-
算法选择:
- 逐位分解:通过
%10和/10逐位提取数字 - 查表映射:用函数
quan(n)将单个数字映射为圈数 - 线性累加:遍历所有位,累加圈数
- 逐位分解:通过
-
关键步骤:
-
初始化:读取整数 \(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\)
- 若
-
-
时间/空间复杂度:
- 时间复杂度:\(O(\log n)\),与数字位数成正比
- 空间复杂度:\(O(1)\),仅需常数变量
-
数位分解的核心思想:
- 十进制逐位提取:
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
浙公网安备 33010602011771号