[信息与未来 2023] 幸运数字 的题解
记住只在没有思路时使用题解,不要从它复制粘贴代码。请尊重题目和题解的作者。
在解题之前提交题解的代码会导致封禁。
在解题之前提交题解的代码会导致封禁。
作者:
概述
本题要求统计区间 内十进制表示的奇数位数字和与偶数位数字和相等的幸运数字个数。核心解法是直接枚举区间内每个数并检查其奇数位、偶数位数字和是否相等;由于
,枚举完全可行。
分析
核心观察
幸运数字只取决于各位数字本身,检查一个数只需 次运算;数据范围
使直接枚举区间内所有数即可在时限内完成。
思路
对区间内每个整数 ,按从左到右的位置(第
位为奇数位,第
位为偶数位)将十进制位分成两组,分别求和,若相等则计数加
。注意从右往左编号得到的分组与此等价(偶数位长度时两组互换,但相等条件对称),因此按从左编号即可。
枚举总代价为 ,在
时约
次运算,足够快;若数据范围更大,可改用数位 DP 在
内求出前缀计数。
具体示例
以样例 为例:
中,一位数
的奇数位和等于其本身而偶数位和为
,均不幸运;两位数中形如
的数幸运,共
个;
的奇数位和
不等于偶数位和
。总计
个,与样例一致。
算法步骤
- 读入
a、b,令计数器cnt为。
- 枚举
x从a到b:- 将
x转为十进制字符串,按位置把各位数字分别累加到奇数位和odd与偶数位和even; - 若
odd等于even,cnt加。
- 将
- 输出
cnt。
复杂度分析
时间:
空间:
实现注意事项
- 位置从
开始编号,如
的奇数位是第
位(数字
)。
- 一位数的偶数位和为
,只有数字本身为
时才可能相等;本题区间从
开始,不受影响。
- 枚举次数最多
,也可用除法和取模逐位提取数字以避免字符串转换开销。
源代码
#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
int cnt = 0;
for (int x = a; x <= b; x++) {
string s = to_string(x);
int odd = 0, even = 0;
for (int i = 0; i < (int)s.size(); i++) {
if (i % 2 == 0) odd += s[i] - '0';
else even += s[i] - '0';
}
if (odd == even) cnt++;
}
cout << cnt << '\n';
return 0;
}
a, b = map(int, input().split())
def is_lucky(x):
s = str(x)
odd = sum(int(c) for i, c in enumerate(s) if i % 2 == 0)
even = sum(int(c) for i, c in enumerate(s) if i % 2 == 1)
return odd == even
print(sum(1 for x in range(a, b + 1) if is_lucky(x)))
评论