(二分,BFS).Treasure Island

I. Treasure Island

1000ms
1000ms
262144KB
64-bit integer IO format:  %lld      Java class name:  Main
Font Size:   

Finding the treasures hidden centuries ago by the pirates of the Caribbean islands is no easy task, but even more difficult is living to tell the story. This is because, as everybody knows, pirates had supernatural powers which they used to curse the person who took their treasure unauthorized.

A very common curse among the most powerful of pirates, and for which it is always a good idea to be prepared, is known today as the deadly mist. Whenever a pirate's treasure is found, this curse will make a poisonous mist lift from the ground until the whole island gets covered by it. Any living creature that is touched by the mist will die instantly, something especially undesirable for those who have just found a treasure. The only way to save yourself is then to return to your boat, always going through areas that have not yet been covered by the mist, and thus flee with that part of the treasure that may have been rescued. In this problem we are interested in knowing what's the maximum amount of time that one can take to collect the treasure in such a way so as to be able to return to the boat alive.

To simplify the problem, we will consider that an island can be represented by a grid with R rows and C columns, in which the cell in the i-th row and the j-th column has height Hij above sea level. Furthermore, we will assume that the treasure is always hidden in the cell in row 1 and column 1, because this is the one furthest away from the only place where the boat can set anchor, which is the cell in row R and column C. The deadly mist appears at sea level at the very same instant that the treasure is found, and then rises on all the island at a rate of one unit of height per second, so that after t seconds one cannot be in any cell of height less or equal to t. In order to return to the boat, you may go from one cell to another only if they share a side, so that if you are on a given cell you can only move horizontally to the cell before or after it in the same row, or vertically to the cell before or after it in the same column, but you cannot move diagonally or cross the boundaries of the island. Each such movement from one cell to another takes exactly one second.

 

Input

The first line contains two integer numbers R and C, respectively the number of rows and columns of the grid that represents the island, which consists of at least two cells (1 ≤ R, C  500 and R×C ≥ 2). Each of the following R lines contains C values. In the i-th of these R lines, the j-th value is an integer Hij representing the height of the cell at row i and column j ( Hij  106 for i = 1, ..., R and j = 1, ..., C).

 

Output

Print a single line containing an integer number representing the maximum amount of time in seconds that one can take to collect the treasure, so as to be able to return to the boat without being reached by the deadly mist. Print the number -1 if it is impossible to return to the boat even if one starts the way back as soon as the treasure is discovered.

 

Example 1

Input:

  
  
3 3
3 3 2 3 4 3 4 5 4 5 6
Output:
1

Example 2

Input:
3 3
1 2 3
2 2 3
2 4 5

Output:
-1

Example 3

Input:
3 2
1000000 1000000
1000000 1000000
1000000 314

Output:
310 


题意:大概就是海平面会上升,每秒上升一,从左上角走到右下角,并且不会被海水淹盖到,问最多可以再左上角这个地方停留多长时间,如果会被淹盖到,那么输出-1.
思路:二分 + bfs! 将你出发的时间进行二分,在此时间下再用广搜,判断有没有一条路径可以到达终点。
#include<queue>
#include<cstdio>
#include<vector>
#include<utility>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define MM 100010
using namespace std;
int R, C;
int vis[510][510];
int h[510][510];
int dp[510][510];
int dx[] = { -1, 0, 1, 0 }, dy[] = { 0, -1, 0, 1 };

int dist[510][510];
queue<int>q;
void bfs(int x, int y,int cnt)
{
	while (!q.empty())q.pop();
	dist[x][y] = cnt;
	q.push(x*C + y);
	while (!q.empty())
	{
		int u = q.front();
		q.pop();
		int x = u / C, y = u%C;
		for (int i = 0; i < 4; i++)
		{
			int xx = x + dx[i], yy = y + dy[i];
			if (xx < 0 || yy < 0 || xx >= R || yy >= C)continue;
			if (dist[xx][yy] != -1)continue;
			if (dist[x][y] + 1 >= h[xx][yy])continue;
			q.push(xx*C + yy);
			dist[xx][yy] = dist[x][y] + 1;
		}
	}
}
int main() {
	int T;
	///freopen("D:\\oo.txt", "r", stdin);
	while (~scanf("%d%d", &R, &C))
	{
		memset(vis,0,sizeof(vis));
		for (int i = 0; i < R; i++)
		{
			for (int j = 0; j < C; j++)scanf("%d", &h[i][j]);
		}
		int res = -1, l = 0, r = h[0][0]-1;
		while (l <= r)
		{
			int mid = l + (r - l) / 2;
			memset(dist, -1, sizeof(dist));
			bfs(0, 0, mid);
			if (dist[R - 1][C - 1] != -1){
				res = max(res, mid);
				l = mid+1;
			}
			else r = mid - 1;
		}
		printf("%d\n", res);
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值