POJ 3278 - Catch That Cow - bfs可行性剪枝加判重

Catch That Cow

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 162098   Accepted: 49347

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 - 1 or + 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

题目大意

对于第i个位置,有三种操作,分别可以走到i - 1, i + 1, i * 2位置,问从位置n走到位置k的最少步骤是多少(其实就是最短路径)

思路

对于这类最短路径我们考虑bfs(广度优先搜索),每一步有三个分支。

如果直接搜索肯定是指数阶级的复杂度,我们需要剪枝来去除无用的节点

1.可行性剪枝:如果当前位置大于k,那么只能不断做X-1操作,而不能使用会使当前位置变大的X+1、2X操作

2.用了可行性剪枝实际还是会超时,因为我们会多次走到相同位置,队列里会产生大量重复节点,而且每次都会push进去的节点数会指数级增长,会导致超时,所以我们还需要用数组标记走过的位置来判重

代码

自认为代码写的还比较优美,注意如果没在bfs里对push进去的节点做范围限制的话,标记数组要开两倍大,不然2X操作会RE

但是我交C++能过,交G++不知道为什么RE了,然后开了三倍大小依然RE,希望有人能告诉我为什么,欢迎拿我代码去实验

#include 
#include 
#include 
using namespace std;
#define mp make_pair
#define fi first
#define se second
typedef pair PII;
const int N = 1e5 + 10;
int vis[N << 1];
queue q;
int main()
{
	int n, k;
	cin >> n >> k;
	q.push(mp(n, 0));
	int ans = 0;
	while (!q.empty()){
		PII tmp = q.front();
		q.pop();
		if (tmp.fi == k) {
			ans = tmp.se;
			break;
		}else {
			if (!vis[tmp.fi - 1])q.push(mp(tmp.fi - 1, tmp.se + 1)), vis[tmp.fi - 1] = 1;
			if (tmp.fi < k){
				if (!vis[tmp.fi + 1])q.push(mp(tmp.fi + 1, tmp.se + 1)), vis[tmp.fi + 1] = 1;
				if (!vis[tmp.fi * 2])q.push(mp(tmp.fi * 2, tmp.se + 1)), vis[tmp.fi * 2] = 1;
			}
		}
	}
	cout << ans << endl;
	return 0;
}

 

你可能感兴趣的:(POJ 3278 - Catch That Cow - bfs可行性剪枝加判重)