小易来到了一条石板路前,每块石板上从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号石板
输入描述:
输入为一行,有两个整数N,M,以空格隔开。 (4 ≤ N ≤ 100000) (N ≤ M ≤ 100000)
输出描述:
输出小易最少需要跳跃的步数,如果不能到达输出-1
输入例子:
4 24
输出例子:
5
思路:假设第一步就是n,下一步就是n加上n的约数,得到n的所有的约数和n相加的数就是第二步能到达的石板数。如题:开始是4,第一步只能到6,第二步到8和9,第三步就可以到10,12,第四步可以到12,15,14,15,16,18,我们第三步就到了12,所以到达12的最小步数就是三步。第五步可以到达24。
代码:
void getys(int n, vector<int>&ys)
{
for (int i = 2; i<n; i++)
{
if (n%i == 0)
ys.push_back(i);
}
}
int main()
{
int n, m;
while (cin >> n >> m)
{
vector<int> arr(m+1, -1);//到达当前石板用的最小步数
arr[n] = 0;
for (int i = n; i<=m; i++)
{
if (arr[i] == -1)//不能到达
continue;
vector<int> ys;
getys(i, ys);
for (int j = 0; j < ys.size(); j++)
{
if (i + ys[j] <= m)
{
if (arr[i + ys[j]] == -1)//没到达过这个石板
arr[i + ys[j]] = arr[i] + 1;
else//多次到达求最小的步数
{
arr[i + ys[j]] = min(arr[i] + 1, arr[i + ys[j]]);
}
}
}
}
if (arr[m] == 0)
cout << "-1" << endl;
else
cout << arr[m] << endl;
}
return 0;
}