专栏文章
数字存在性问题研究
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @min49k56
- 此快照首次捕获于
- 2025/12/01 20:19 3 个月前
- 此快照最后确认于
- 2025/12/01 20:19 3 个月前
[ABC077D] Small Multiple
Problem
给定一个整数 。求一个 的正整数倍 ,使得 的数位累加和最小。
Solution
很容易发现答案必然小于或等于 的数位累加和 ,那么问题就转化为了是否存在一个数 ,满足数位和为 且 ,如果存在答案就是 。
如果题目是这样的:
统计 中满足数位和等于 且 的整数 的个数。
熟悉吗?这就是很朴素的数位 DP。
有什么不同呢?
- 本题不关心范围
- 本题不关心个数
也就是说我们只关心能不能成功构造出一个数字,此时
pos 是无意义的,因为位置是无限的。所以我们只要记录当前的 state ——也就是数位和 sum 和余数 remainder,暴力加数转移即可。使用
Cbfs 保证找到的一定是最小的数(没啥用就是了)。#include <bits/stdc++.h>
using namespace std;
int k;
bool vis[100005][60];
void bfs() {
queue<pair<int, int> > q;
for(int i = 1; i <= 9; i++) {
int remainder = i % k;
int sum = i;
if(!vis[remainder][sum]) {
vis[remainder][sum] = true;
q.push({remainder, sum});
}
}
while(!q.empty()) {
auto [remainder, sum] = q.front();
q.pop();
for(int i = 0; i <= 9; i++) {
int new_remainder = (remainder * 10 + i) % k;
int new_sum = sum + i;
if(new_sum <= 55 && !vis[new_remainder][new_sum]) {
vis[new_remainder][new_sum] = true;
q.push({new_remainder, new_sum});
}
}
}
}
int main() {
cin >> k;
bfs();
for(int i = 1; i <= 55; i++) {
if(vis[0][i]) {
cout << i;
break;
}
}
return 0;
}
[ABC423G] Small Multiple 2
Problem
求满足以下两个条件的正整数 的最小可能值:
- 是 的倍数。
- 的十进制表示中包含 作为子串。
Solution
答案必然为 形式,且保证有一个解为 ,所以答案长度必然小于或等于 。
由基本不等式得 ,故我们可以枚举 和 ,并解出对应的 和 。
这里有个细节, 的前导零是有意义的,所以我们还要枚举后缀长度 ,因此 来保证有前导零。
枚举 时:
显然 。
枚举 时:
这里要用扩展欧几里得算法求最小非负解 。
最后找最小的答案即可。
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...