poj 2110 Mountain Walking(二分 + 枚举 + bfs)

点击打开链接

该题的大致题意:

给你一个N * N的海拔分布图, 此时农民John在(1,1)处, 而他的度假小屋在(N,N)处, 现在他想要从(1,1)处

找出一条到达(N,N)处的路径,这条路径应该满足这样的要求:最高海拔和最低海拔的差值最小。并且John只

能向北,向南,向东,向西走。


我们能很轻易的想到要用搜索去找到这样一条路径,但是搜索一般是盲目的搜(换句话说,搜索会找到从(1,1)

到(N,N)的所有路径),它并不能找到我们想要的路径。 但是我们可以给搜索加上条件,就能找到我们想要的

路径了。


可以想到限制搜索的范围,我们可以枚举一个最高海拔,一个最低海拔。让搜索在这个范围内进行搜索,如果

能达到终点,说明该次搜索是有效的。


以上,我们能想到可以二分找到一个海拔差值,然后结合这个值和海拔总范围不断枚举一个最高海拔和最低

海拔。接着我们去搜索看能不能找到一条合法的路径。在不断枚举并搜索的过程中,只要有一次枚举的最高

海拔和最低海拔可以找到一条合法路径,说明这次二分的海拔差值是有效的,但是这并不是我们想要的(因为

这个差值可能不是最小的),所以我们需要缩小二分的右区间,继续寻找最小的海拔差值。否则的话我们就增

大左区间,直到左区间大于右区间


代码如下:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;

const int INF = 110;

struct node
{
	int x,  y;
};

int data[INF + 5][INF + 5];			//存地图 

int bfs(int low, int high);		//广搜,看能否在海拔范围为low,high中找到一条合法路径 

int judge(int diff);			//判断这个差值是否有效 

int BinarySearch(int left, int right);	//二分的过程 

int dir[4][2] = {-1,0,0,-1,1,0,0,1}; 	//广搜的方向

int vis[INF + 5][INF + 5] = {0};			//用来在标记已经搜索到的点 

int N;

/*
5
1 1 3 6 8
1 2 2 5 5
4 4 0 3 3
8 0 2 3 4
4 3 0 2 1
*/
int main()
{
	scanf("%d", &N);
	
	for(int i = 1; i <= N ;i++)
	{
		for(int j = 1; j <= N; j++)
		scanf("%d", &data[i][j]);
	}
	
	int result = BinarySearch(0,INF);
	
	printf("%d\n", result);
	
	
	
	return 0;
}

int BinarySearch(int left, int right) 
{
	
	
	while(left <= right)
	{
		int mid = (left + right) / 2;
		
		if(judge(mid) == 1)
		{
			right = mid - 1;
		}
		else
		{
			left = mid + 1;
		}
		

	}
	
	return left;
	
	
}

int judge(int diff)
{
	for(int i = 0 ; i + diff <= INF ;i++)
	{
		if(bfs(i, i + diff) == 1)
		{
			return 1;
		}
	}
	return 0;
	
	
}

int bfs(int low, int high)
{
	memset(vis, 0, sizeof(vis));
	
	node start; start.x = 1; start.y = 1;     //广搜的起点
	
	if(!(data[1][1] >= low && data[1][1] <= high))
	return 0;
	
	queue <node> que;
	
	que.push(start); vis[1][1] = 1;
	
	while(!que.empty())
	{
		node now = que.front(); que.pop();
		
		if(now.x == N && now.y == N)
		return 1;
		
		for(int i = 0 ; i < 4; i++)
		{
			int nx = now.x + dir[i][0];
			
			int ny = now.y + dir[i][1];
			
			if(nx >= 1&& nx <= N && ny >= 1 && ny <= N && data[nx][ny] >= low && data[nx][ny] <= high && vis[nx][ny] == 0)
			{
				vis[nx][ny] = 1;
				
				node temp;temp.x = nx; temp.y = ny;
				
				que.push(temp);
				
			}
		}
	}
	return 0;
	
	 
	
	
}




猜你喜欢

转载自blog.csdn.net/u013377068/article/details/79890727