题解:学而思编程 特殊数字1

【题目来源】

学而思编程:特殊数字1

【题目描述】

如果一个十进制正整数能够被它的每一个非零数码整除,则称它为特殊数字,比如 \(408\) 是一个特殊数字,因为 \(408\) 能被 \(4\)\(8\) 整除,而 \(1023\) 不是,因为它不能被 \(2\) 整除。给定一个正整数 \(n\),请判定它是否为特殊数字。

【输入】

第一行包含整数 \(T\),表示共有 \(T\) 组测试数据。

每组数据占一行,包含一个整数 \(n\)

【输出】

每组数据输出一行结果,如果 \(n\) 是一个特殊数字,输出 Yes;否则,输出 No。

【输入样例】

2
102
2050

【输出样例】

Yes
Yes

【核心思想】

  1. 问题分析:给定一个正整数 \(n\),需要判定 \(n\) 是否能被其十进制表示中的每一个非零数码整除。这是一个数位拆分 + 整除判定问题,关键在于逐位提取数字并进行整除检验。

  2. 算法选择

    • 数位拆分(Digit Extraction):通过取模和整除操作逐位提取 \(n\) 的十进制数码
    • 模拟验证:对每个非零数码 \(d\),检验 \(n \bmod d = 0\) 是否成立
  3. 关键步骤

    • 读取输入:读取测试用例数量 \(T\)
    • 逐组处理(循环 \(T\) 次):
      • 读取整数 \(n\)
      • 数位检验:令 \(t = n\)(保留 \(n\) 的副本用于检验),当 \(t > 0\) 时循环:
        • 提取最低位数码:\(a = t \bmod 10\)
        • 跳过零数码:若 \(a = 0\),直接跳过(零不能作为除数)
        • 整除判定:若 \(a \neq 0\)\(n \bmod a \neq 0\),则 \(n\) 不是特殊数字,返回 false
        • 去掉已检验的最低位:\(t \leftarrow t / 10\)
      • 若所有非零数码均通过检验,返回 true
    • 输出结果:根据 check(n) 的结果输出 YesNo
  4. 时间/空间复杂度

    • 时间复杂度:\(O(T \times \log_{10} n)\),每组数据需遍历 \(n\) 的所有十进制位数,位数为 \(\lfloor \log_{10} n \rfloor + 1\)
    • 空间复杂度:\(O(1)\),仅使用常数个变量,无需额外数组
  5. 数位模拟的核心思想

    • 取模拆位:利用 \(t \bmod 10\) 获取最低位数码,\(t / 10\) 右移一位,实现 \(O(1)\) 的逐位提取
    • 原数保留技巧:检验时用 \(t\) 遍历各位,但整除判定使用原始值 \(n\)(而非 \(t\)),因为 \(t\) 在拆位过程中不断变小,而检验条件要求被除数是完整的 \(n\)
    • 零的特殊处理:数码 \(0\) 必须跳过,因为除数不能为零;题目定义也明确只要求被"非零数码"整除
    • 短路优化:一旦发现某个数码不能整除 \(n\),立即返回 false,无需继续检验剩余位数
    • 适用于数位相关判定、数字特征检验类问题

【算法标签】

模拟

【代码详解】

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

#define int long long  // 定义int为long long类型
int t;  // 测试用例数量

// 检查数字x是否满足条件
bool check(int x)
{
    int t = x;  // 保存x的副本
    while (t)  // 遍历x的每一位数字
    {
        int a = t % 10;  // 获取当前最低位数字
        if (a && x % a)  // 如果数字不为0且x不能被这个数字整除
        {
            return false;  // 不满足条件
        }
        t /= 10;  // 去掉最低位
    }
    return true;  // 所有数字都满足条件
}

signed main()  // 因为定义了#define int long long,所以用signed代替int
{
    cin >> t;  // 输入测试用例数量

    while (t--)  // 处理每个测试用例
    {
        int n;
        cin >> n;  // 输入要检查的数字

        if (check(n))  // 如果满足条件
        {
            cout << "Yes" << endl;  // 输出Yes
        }
        else
        {
            cout << "No" << endl;  // 输出No
        }
    }

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

【运行结果】

2
102
Yes
2050
Yes
posted @ 2026-07-05 16:03  团爸讲算法  阅读(5)  评论(0)    收藏  举报