POJ 3278 Catch That Cow

题意: 给定两个整数n和k

通过 n+1或n-1 或n*2 这3种操作,使得n==k

输出最少的操作次数

思路:   3个方向的BFS【+1,-1,*2】

注意:  因为数据比较大,直接套模板BFS会TLE,

应该适当剪枝:

1,当n>=k时,直接可知最少步数n-k【只能通过后退一步来到达位置k】

如果此处进入BFS则会浪费很多时间!

2,如果BFS到当前位置大于k,那么以后的+1都不会到达小牛的位置。

也只能通过后退一步的方式来达到k,所以当当前位置大于k是不需要

继续判断+1的情况了。

3,同2,如果当前位置比k还大,也是只能通过后退的方式达到k,

所以*2的情况也不用考虑。


/*
POJ 3278
问题1186
Memory 5400
Time 1420
*/
#include<iostream>
#include<cstring>
#include<queue>
#include<stdio.h>
using namespace std;
const int MAXN = 1000050;
int vis[MAXN+1];
int n, k;
struct Node
{
	int x, step;
};
int bfs(int start)
{
	memset(vis, 0, sizeof(vis));
	queue<Node>Q;
	Node temp;
	temp.x = start;
	temp.step = 0;
	vis[temp.x] = 1;
	Q.push(temp);
	while (!Q.empty())
	{
		Node h;
		h = Q.front();
		Q.pop();
		if (h.x == k)
		{
			return h.step;
		}
		if (h.x + 1 <= k&&vis[h.x + 1] == 0)//剪枝,如果当前位置大于k,
		{                            //那么以后的+1都不会到达小牛的位置。
			Node next;
			vis[h.x + 1] = 1;
			next.x = h.x + 1;
			next.step = h.step + 1;
			Q.push(next);
		}
		if (h.x - 1 >= 0 && vis[h.x - 1] == 0)
		{
			Node next;
			vis[h.x - 1] = 1;
			next.x = h.x - 1;
			next.step = h.step + 1;
			Q.push(next);
		}
		if ((h.x <= k)&&(h.x * 2 <= MAXN) && vis[h.x * 2] == 0)
		{                            //如果当前位置比k还大那么下一次*2会更大
			Node next;              //后退只能-1,那么本来就比k大,那么可以后退
			vis[h.x * 2] = 1;       //(当前位置步-k步),而再*2那就得后退(当前位置*2-k步)
			next.x = h.x * 2;            
			next.step = h.step + 1;
			Q.push(next);
		}
	}
	return 0;
}
int main()
{
	while (scanf("%d %d",&n,&k)!=EOF)
	{
		if (n >= k)//剪枝,当n大于k时,n只能通过后退
		{          //一步来达到k,不需要进入bfs,不然会TLE
			cout << n - k << endl;
		}
		else
		{
			printf("%d\n", bfs(n));
		}
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值