T3-3 Required Length
2026-01-30 11:00:07
发布于:浙江
2阅读
0回复
0点赞
题意理解
给定整数 和 ,每次操作可以选择 十进制表示中的某个非零数字 ,将 替换为 。求使 的十进制长度恰好变为 的最少操作次数。
思路分析
BFS 求最短路
由于要求最少操作次数,这是一个典型的 BFS 问题。每个数值是一个状态,每次操作是一条边。
关键观察:
- 乘以 :结果变成 ,永远无法增长,无意义
- 乘以 :数值不变,无意义
- 乘以 :数值严格增大,长度不减
因此只需考虑乘以 的数字。
无解情况:
如果 只包含数字 和 ,那么只能乘 ,数值永远不变,无法达到更大的长度。
算法流程:
- 如果初始长度已达到 ,输出
- 用队列进行 BFS,初始状态为
- 每次取出当前数 ,枚举其所有 的数字 ,计算
- 若 长度达到 ,返回步数
- 若 长度 且未访问过,加入队列
- 队列为空仍未达到,返回
参考代码
#include <bits/stdc++.h>
using namespace std;
int getLen(long long x) { // 获取x的十进制长度
int len = 0;
while (x) { // 逐位统计
len++;
x /= 10;
}
return len;
}
int main() {
int n;
long long x;
cin >> n >> x; // 读入目标长度和初始数
if (getLen(x) == n) { // 初始长度已达到目标
cout << 0 << endl;
return 0;
}
set<long long> vis; // 记录访问过的状态
queue<pair<long long, int>> q; // 队列存储(当前数, 操作次数)
q.push({x, 0}); // 初始状态入队
vis.insert(x); // 标记已访问
while (!q.empty()) { // BFS主循环
long long cur = q.front().first; // 当前数
int step = q.front().second; // 当前操作次数
q.pop();
set<int> digits; // 提取cur的所有数字(去重)
long long tmp = cur;
while (tmp) {
int d = tmp % 10;
if (d >= 2) digits.insert(d); // 只考虑>=2的数字
tmp /= 10;
}
for (int d : digits) { // 枚举可乘的数字
long long nxt = cur * d; // 计算新的数
if (getLen(nxt) == n) { // 达到目标长度
cout << step + 1 << endl;
return 0;
}
if (getLen(nxt) < n && vis.find(nxt) == vis.end()) { // 长度未超且未访问
vis.insert(nxt); // 标记访问
q.push({nxt, step + 1}); // 入队继续搜索
}
}
}
cout << -1 << endl; // 无法达到目标
return 0;
}
这里空空如也


有帮助,赞一个