vjudge-Catch That Cow

vjudge-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
5 17
Sample Output
4
Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

中文版
‎农夫约翰已经被告知一头逃逸的奶牛的位置,并希望立即抓住她。他从数字行上的‎‎点 N‎‎ (0 ≤ ‎‎N‎‎ ≤ 100,000) 开始,而牛在同一数字行上从‎‎点 K‎‎ (0 ≤ ‎‎K‎‎ ≤ 100,000) 开始。农民约翰有两种交通方式:步行和传送。‎

‎* 步行:FJ 可以在‎‎一分钟内从任何点‎‎ ‎‎X‎‎移动到点‎‎X ‎‎- 1 或‎
‎X = 1 * 传送:FJ 可以在一分钟内从‎‎任何点 X‎‎移动到点 2 × ‎‎X。‎

‎如果牛,不知道它的追求,不移动,多久农民约翰要找回它?‎

‎输入‎
‎第 1 行:两个空格分隔的整数‎‎:N‎‎和‎‎K‎
‎输出‎
‎第1行:用最少的时间,在几分钟内,农民约翰需要抓住逃亡的牛。‎
‎示例输入‎
5 17
‎样品输出‎
4
‎提示‎
‎农民约翰到达逃逸牛的最快方式是沿着以下道路移动:5-10-9-18-17,这需要4分钟。‎

这里我们使用广度优先搜索(BFS)来写
广度优先搜索: 在广度优先搜索算法中,解答树上结点的扩展是按它们在树中的层次进行的。首先生成第一层结点,同时检查目标结点是否在所生成的结点中,如果不在,则将所有的第一层结点逐一扩展,得到第二层结点,并检查第二层结点是否包含目标结点,……,对层次为n+1的任一结点进行扩展之前,必须先考虑层次完层次为n的结点的每种可能的状态。因此,对于同一层结点来说,求解问题的价值是相同的,可以按任意顺序来扩展它们。通常采用的原则是先生成的结点先扩展。因此储存队列主要用队列这种数据结构

BFS的伪代码
将初始结点压入队列
标记该结点
while 队列不为空
{
取出队首结点
判断队首结点是否为答案
若为答案则退出
若不为答案
{
循环遍历改结点的情况
砍断该状态是否可行
若状态不可行 —继续判断下一个状态
若状态可行
标记该状态
将状态压入队列
}
}
以下是有解释代码

#include <bits/stdc++.h>//这里使用了万能头,我的vjudge过不了,我重新换了个
using namespace std;
int N,K;
const int maxn=100000;//最大长度
int vis[maxn+10];
struct step//建立一个叫step的结构体
{
	int x;//位置 
	int steps;//到达x所需的步数
	step(int xx,int s):x(xx),steps(s){} 
	//结构体step的构造函数
	//Step(int xx, int s){
    //x = xx;
   //steps = s;
   // }
};
queue <step> q;//队列,即open表 
int main()
{
	cin>>N>>K;
	memset(vis,0,sizeof(vis));//使用memset函数给vis赋值

	//BFS伪代码套进去
	q.push(step(N,0)); //初始结点压入队列
	vis[N]=1;//标记该结点
	
	while(!q.empty())
	{
		step s=q.front();//取出首结点
		if(s.x==K)//判断是否为答案,就是我们需要寻找的K
		{
			cout<<s.steps<<endl;//若为答案就输出 
			return 0;
		}
		else //如果不是答案 遍历该结点的情况,转移到下一个状态 
		{
			if(s.x-1>=0&&!vis[s.x-1])//判断 -1 的状态是否可行 
			{
				q.push(step(s.x-1,s.steps+1));//压入队列
				vis[s.x-1]=1;//标记状态
			}
			if(s.x+1<=maxn&&!vis[s.x+1])//判断 +1 的状态是否可行 
			{
				q.push(step(s.x+1,s.steps+1));
				vis[s.x+1]=1;
			}
			if(s.x*2<=maxn&&!vis[s.x*2])//判断 *2 的状态是否可行 
			{
				q.push(step(s.x*2,s.steps+1));
				vis[s.x*2]=1;
			}
			q.pop();//删除队首元素
		 } 
		 
	}
	return 0;
}

以下是没有解释的代码

#include <bits/stdc++.h>
using namespace std;
int N,K;
const int maxn=100000;
int vis[maxn+10];
struct step
{
	int x;
	int steps;
	step(int xx,int s):x(xx),steps(s){} 
};
queue <step> q;
{
	cin>>N>>K;
	memset(vis,0,sizeof(vis));
	q.push(step(N,0));
	vis[N]=1;
	
	while(!q.empty())
	{
		step s=q.front();
		if(s.x==K)
		{
			cout<<s.steps<<endl;
			return 0;
		}
		else 
		{
			if(s.x-1>=0&&!vis[s.x-1])
			{
				q.push(step(s.x-1,s.steps+1));
				vis[s.x-1]=1;
			}
			if(s.x+1<=maxn&&!vis[s.x+1])
			{
				q.push(step(s.x+1,s.steps+1));
				vis[s.x+1]=1;
			}
			if(s.x*2<=maxn&&!vis[s.x*2])
			{
				q.push(step(s.x*2,s.steps+1));
				vis[s.x*2]=1;
			}
			q.pop();
		 } 
		 
	}
	return 0;
}

运行截图如下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值