HDU2717:Catch That Cow

点击打开题目链接

Catch That Cow

Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4293    Accepted Submission(s): 1382


Problem Description
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.
 

Source
USACO 2007 Open Silver
 

Recommend
teddy
 


=====================================算法分析=====================================


BFS+剪枝(注意数组不要越界)。


=======================================剪枝=======================================


设John的坐标为X[John],牛的坐标为X[cow]。
       

一、移动方法A(坐标加一)的剪枝:


    一旦X[John]>X[cow],再往右走就没有意义了,因此只有在X[John]<X[cow]时才需使用移动方法A


二、移动方法B(坐标翻倍)的剪枝:


    假设:John使用移动方法B后X[John]>X[cow](即当前有2X[John]>X[cow])。

    如果:1、John选择使用移动方法B,则其最小移动次数显然为1+2X[John]-X[cow]。

          2、John放弃使用移动方法B,则其最小移动次数不会超过X[cow]-X[John]。

    那么:需要选择移动方法B的前提是1+2X[John]-X[cow]<X[cow]-X[John]即3X[John]≤2X[cow]。

    又因:2X[John]≤X[cow]的情况下3X[John]≤2X[cow]是显然成立的。

    因此:只有在3X[John]≤2X[cow]时才需使用移动方法B


=======================================代码=======================================



#include<queue>
#include<cstdio>
#include<cstring>

using namespace std;

const int MAXC=100000;

int N,K,Step[MAXC+5];

int BFS()
{
	if(N==K) return 0;
	memset(Step,-1,sizeof(Step));
	Step[N]=0; 
	queue<int>q;   
	for(q.push(N);!q.empty();q.pop())
	{
		int cur=q.front(); 
		for(int n=0;n<3;++n)
		{
			int tmp=cur;
			if(n==0)
			{
				if(tmp*2<=MAXC&&tmp*3<=K*2) tmp*=2;
				else continue;
			}
	        else if(n==1)
			{
				if(tmp+1<=K) ++tmp;
				else continue;
			}
			else if(n==2)
			{
				if(tmp-1>=0) --tmp;
				else continue;
			}
			if(Step[tmp]==-1)
			{
				Step[tmp]=Step[cur]+1;
				if(tmp==K) return Step[tmp];
			    q.push(tmp);
			}
		}
	}
}

int main()
{
	while(scanf("%d%d",&N,&K)==2) 
	{
		printf("%d\n",BFS());
	}
	return 0;
}

你可能感兴趣的:(搜索,bfs,剪枝)