2025年【江苏“信息与未来”编程思维】真题及题解(T1:幸运数字)

2025年【江苏"信息与未来"编程思维】真题及题解(T1:幸运数字)

题目描述

如果一个 n n n 位正整数恰好由数字 0 , 1 , 2 , ⋯   , n − 1 0, 1, 2, \cdots , n - 1 0,1,2,⋯,n−1 组成,Dr. X 就称它为"幸运数字",例如:

  • 1023 1023 1023 是一个幸运数字,因为它是一个四位数,且恰好由数字 0 , 1 , 2 , 3 0, 1, 2, 3 0,1,2,3 组成。
  • 123 123 123 不是幸运数字,因为三位幸运数字应该由数字 0 , 1 , 2 0, 1, 2 0,1,2 组成。
  • 012 012 012 不是幸运数字,因为我们只考虑不含前导零的正整数。

现在,给定两个正整数 a a a 和 b b b,请你计算 a , a + 1 , a + 2 , ⋯   , b a, a + 1, a + 2, \cdots, b a,a+1,a+2,⋯,b 中幸运数字的数量。

输入格式

输入两个空格分隔的正整数 a a a 和 b b b。

输出格式

输出一个整数,表示 a , a + 1 , a + 2 , ⋯   , b a, a + 1, a + 2, \cdots, b a,a+1,a+2,⋯,b 中幸运数字的数量。

输入输出样例 1
输入 1
复制代码
4 202
输出 1
复制代码
4
输入输出样例 2
输入 2
复制代码
1 100000
输出 2
复制代码
119

说明/提示

样例 1 \textbf 1 1 解释

在 4 4 4 和 202 202 202 之间,幸运数字有 10 , 102 , 120 , 201 10, 102, 120, 201 10,102,120,201。

数据范围

对于 100 % 100\% 100% 的数据,满足 1 ≤ a ≤ b ≤ 10 6 1 ≤ a ≤ b ≤ 10^6 1≤a≤b≤106。

思路分析

幸运数字的定义:对于一个 n 位的正整数,它必须恰好由数字 0, 1, 2, ..., n-1 各出现一次组成,且不能包含其他数字。

例如 1023(4位)由 0,1,2,3 各一次,是幸运数字;123(3位)缺少 0 且包含 3,不是。

判断方法:

  1. 求出位数 n,并用计数数组 c[10] 记录每个数字(0~9)出现的次数。
  2. 检查数字 0n-1 是否都恰好出现一次。
    • 因为总位数恰好为 n,如果 0~n-1 各出现一次,则位数已经占满,不可能再出现其他数字。
  3. 满足则返回 true,否则返回 false

区间长度最大为 10 6 10^6 106,每个数最多 7 位,暴力枚举判断足够高效。


代码实现

cpp 复制代码
#include <bits/stdc++.h>   
using namespace std;

int a,b;  // 区间左右端点

bool check(int x){ // 判断x(>0)是否为幸运数字
    int n=0,c[10]={0}; // n:位数, t:临时副本, c:数字计数
    while(x>0){ // 逐位分解
        c[x%10]++; // 统计该数字出现次数
        x/=10;             
        n++; // 位数累加
    }
    for(int i=0;i<n;i++){// 检查0~n-1是否都恰好出现一次
        if(c[i]!=1) return false; // 不满足则不是幸运数字
    }
    return true; // 全部满足,是幸运数字
}

int main(){
    cin>>a>>b; 
    int s=0; // 计数器
    for(int i=a;i<=b;i++){ // 遍历区间内所有整数
        if(check(i)) s++; // 是幸运数字则累加
    }
    cout<<s; 
    return 0;
}

功能分析

  • 核心函数 check

    通过统计数字出现次数并验证 0位数-1 是否各出现一次,高效判断一个数是否为幸运数字。

    由于位数有限(≤7),数组 c 大小固定为 10,时间开销极小。

  • 主函数逻辑

    读取区间 [a,b],枚举每个整数,调用 check 累加合法个数,最后输出答案。

  • 复杂度

    时间复杂度 O((b-a+1) · log₁₀ b),最坏约 10⁶ × 7 次操作,可在 1 秒内完成。

    空间复杂度 O(1),仅使用常数大小的数组。


各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:

https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:

https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:

https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:

https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转

信奥赛C++普及组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):

https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}