每日一题:跳石板

小易来到了一条石板路前,每块石板上从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;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值