题目描述
每块石板上从1挨着编号为:1、2、3…这条石板路要根据特殊的规则才能前进:对于当前所在的编号为K的 石板,单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 当前处在编号为N的石板,想跳到编号恰好为M的石板去,想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是最少需要跳跃5次,就可以从4号石板跳到24号石板
示例1
输入:4 24
输出:5
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
//计算约数
void Y_sum(int n, vector<int>&num)
{
for (int i = 2; i <= sqrt(n); i++)
{
if (n%i == 0)
{
num.push_back(i);
//约数*约数=num
if (n / i != i)
{
num.push_back(n / i);
}
}
}
}
int jump(int N, int M)
{
//计算N到每一步的距离,其中N到N为1步
vector<int> step_num(M + 1, 0);
step_num[N] = 1;
for (int i = N; i < M; i++)
{
//N的所有约数,表示从本身这个点开始可以走的数量
vector<int> divnum;
if (step_num[i] == 0)
{
continue;
}
//求出所有能走的步数
Y_sum(i, divnum);
for (int j = 0; j < divnum.size(); j++)
{
//由位置i出发的能到达的点为step_num[divnum[j]+i]
if ((divnum[j] + i) <= M && step_num[divnum[j] + i] != 0)
{
step_num[divnum[j] + i] = min(step_num[divnum[j] + i], step_num[i] + 1);
}
else if ((divnum[j] + i) <= M)
{
step_num[divnum[j] + i] = step_num[i] + 1;
}
}
}
if (step_num[M] == 0)
{
return -1;
}
else
return step_num[M] - 1;
}
int main()
{
int n, m;
cin >> n >> m;
cout << jump(n, m) << endl;
system("pause");
return 0;
}