每日一题:跳石板

博客围绕小易在石板路上的跳跃问题展开。小易在编号为N的石板,要跳到编号为M的石板,单次只能往前跳K(当前石板编号)的非1和本身的约数步。给出输入输出示例,还阐述了计算最少跳跃步数的思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值