为了解决这个问题,我们可以编写一个函数来计算从编号为1的石头到达编号为n的石头所需的最少步数。问题的关键是理解每一步的移动规则:从当前石头编号n移动到编号为n+x的石头上,其中x是n的各位数字之和。因此,我们需要一个辅助函数来计算一个数字的各位数之和。
#include <bits/stdc++.h>
using namespace std;
// 计算一个整数的各位数字之和
int digitSum(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
// 计算从1号石头到达编号为n的石头的最少步数
int minStepsToOne(int n) {
vector<int> steps(n+1, -1); // 存储到每个编号的最少步数,初始化为-1
steps[1] = 0; // 从1号石头出发,步数为0
queue<int> q;
q.push(1); // 将1号石头加入队列
// BFS算法
while (!q.empty()) {
int current = q.front();
q.pop();
if (current == n) {
return steps[current]; // 如果到达目标石头,返回步数
}
int next_step = current + digitSum(current);
if (next_step <= n && steps[next_step] == -1) {
q.push(next_step);
steps[next_step] = steps[current] + 1; // 更新步数
}
}
return -1; // 如果队列为空,说明无法到达
}
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
cout << minStepsToOne(n) << '\n';
}
return 0;
}
这个程序使用了广度优先搜索 (BFS) 来寻找最少步数。对于每个询问,我们创建一个大小为n+1的steps数组,用来存储从1号石头到达每个编号石头的最少步数。我们还使用了一个队列q来存储待处理的石头编号。通过不断地取队列前端的石头编号,计算下一步可以到达的石头编号,并更新steps数组,直到找到目标石头编号或队列为空。