Catch That Cow

Catch That Cow

题目描述:

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

  • Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
  • Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input:

Line 1: Two space-separated integers: N and K

Output:

Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input:

在这里插入图片描述

Sample Output:

在这里插入图片描述

Hint(提示):

在这里插入图片描述

题目大意:

有一个养牛场,主人发现其中有一头牛的逃跑了,他要去追回这头牛,抓住这只逃跑的牛,牛将会在那个地方不动,等着主人来抓,主人有3种移动方式,每种移动方式都以分钟为单位,有走一步,退一步,传送。这里传送指的是当前位置是4,你只能传送2倍后的位置就是8。
题目输入N,K,分别是主人和牛的位置,要求你输出最少分钟抓到这只逃跑的牛。

思路分析:

这里有2种角度,可以从人抓牛,或者牛去追人来去思考,如果人去抓牛的话,如果是第一种人抓牛可以用枚举加dfs去做,但是我不会,所以我选择了第二种,牛追人,可以用简单的递归加DFS去写就能写出来,牛去追人的话可以看成这样。
假设N<K的时候,就只能走一种路线就是退着走,用了k-m分钟
假设N>K的时候,分2种情况,第一种:如果K%2=0,这里继续细分3种情况,当m==k/2的时候,说明直接一步传送就行,当m<k/2的时候,继续递归令k=k/2,因为牛缩减一半,要用1分钟传送,所以要加1,剩下减去就行了,当m>k/2的时候,要比较2种方式所用的最短时间,一种直接用k-m的方式所用时间,一种用m-k/2+1所用的时间。
第二种:当k%2!=0,先将牛先走一步或者退一步,将其变成偶数,继续以下递归,并且判断先走一步和退一步接下来递归所用时间谁最少。
这里要注意m=0的时候,一旦m=0,必须要自增让其变成1,去递归,要不然WA。

代码:

#include<iostream>
#include<stdio.h>
using namespace std;
int LemonDFS(int m,int k)
{
	if(m>=k)//当m>k,说明只能退者走,这一种方式 
	{
		return m-k;
	}
	if(k%2==0)//如果k%2==0 
	{
		if(m<k/2)//如果m小于k/2,将牛的位置缩小一半继续递归 
		{
			return LemonDFS(m,k/2)+1;//这里加1,是因为牛缩小一半,用了传送。所以加1分钟 
		}
		else if(m==k/2)//m==k/2 
		{
			return 1;//直接用传送这一步,花费一分钟 
		}
		else if(m>k/2)//如果m>k/2 
		{
			return min(1+m-k/2,k-m);//这里有2种行走方式,一种是牛的位置减半,然后用m去
			//减去k/2,一步一步走过去,或者直接用k-m计算2者的所要的min。 
		}
		
	}
	else
	//如果k%2!=0,那么将其多走一步,或者少走一步,然后继续递归
	//因为奇数加1或者减1,必然是偶数,k%2==0,继续递归找出满足条件。 
	return min(LemonDFS(m,k+1),LemonDFS(m,k-1))+1;//这里加1,是因为增了一步和减了一步,
	//多用了1分钟,这里比较是多走一步还是少走一步,所用的时间最少用了min函数来找 
}
int main()
{
	int flag=0;
	int m,k;
	scanf("%d %d",&m,&k);
	if(m==0)//这里注意,题目没说m不能等于0,当m=0,必须要自行加1 
	{
		flag=1; 
	}
	printf("%d",LemonDFS(m+flag,k)+flag);//flag为min数,m=0的时候,自行加一分钟。 
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值