UCF Local Programming Contest 2016 J Rising Tides 【二分】

Description

Last May, the UCF Programming Team attended the ACM ICPC World Finals in Phuket, Thailand. Besides the exciting programming contest, Thailand had some great sights to see! 

The Phang Nga Bay in Thailand is home to hundreds of islands, some of which (e.g., James Bond Island) are famous from movie scenes. Others have lagoons inside that can only be reached by canoeing through caves on the water. Some caves have ceilings so low that canoers must lean over to make it through. 

MAVK8IYGLRDGKKQG4GDK%0I.png

Besides navigating the tricky passages of the caves, canoers must be aware of the tides. Some caves can only be traversed in low tide. As the tides change, the sea level rises or falls while the explorers are paddling, and they must be careful to choose the correct path through the cave to avoid getting trapped. Of course, if they can make it through, they also want to minimize the amount of energy they spend leaning over in the canoe, i.e., they prefer higher ceiling heights when going through the caves. 

In this problem, we assume that canoers start their journey at low tide and the sea level rises by one millimeter each second. Each cave is described by a two-dimensional grid (table) of numbers, where the j.png number in the i.png row indicates the initial height in millimeters of the cave ceiling at position (݅,݆) on the surface of the water. Because of the sea level change, the ceiling height (the distance from the sea level to the ceiling) at each cell decreases over time. 

The cave can be traversed by starting at the first column of the first row (i.e., northwest corner) and ending at the last column of the last row (i.e., southeast corner). The canoe only moves in one of four directions in the two-dimensional grid (north, south, east, or west), one move at a time. Each second, the canoe moves to an adjacent cell and the sea level increases by one millimeter, and the height of the cell above sea level must be greater than zero when the canoe enters it. The canoe’s move and sea level change happen simultaneously, so the ceiling height may become zero just as the canoe is leaving. You may assume that the height of the cave above the canoe’s initial position is greater than zero. 

Problem

Given the description of a cave, you must find the path with the highest minimum ceiling height, or determine that it is impossible to traverse. Note that the number of cells the path goes through is not important; rather the heights of the cells are important; in particular, you are to find the path with the largest minimum ceiling height.  

Input

The first line of input contains a single positive integer, n, indicating the number of caves to process. This is followed by n cave descriptions. Each cave description begins with a line containing two integers, r and c (1 ≤ r ≤ 500 and 1 ≤ c ≤ 500), denoting the number of rows and columns, respectively. The next r lines each contain c space-separated integers, with the {V7J3J5}%D]CDZC9L1_RK.png number on the PI@%P]9XWU8{F32D1C1L[4S.png line representing the height aij.png(0 ≤aij.png≤ 1000,000,000;a11.png> 0) in millimeters of the cave ceiling above the initial sea level.  

Output

For each cave, output a line with a single integer k denoting the largest minimum ceiling height, in millimeters, of a path through the cave, or the word impossible if the cave can’t be traversed.  

样例输入

2 
4 5 
9 5 4 0 0 
9 4 8 9 12 
9 6 8 7 12 
0 0 9 8 12 
3 1 
10 
1 
10

样例输出

3 
impossible

题目大意:

给定一个n*m的矩阵,矩阵中的值表示洞穴的高度,要从(1,1)走到(n,m),同时每走一步矩阵中的值都会减一,要求最大化从(1,1)到(n,m)的路径中的洞穴高度(动态高度)的最小值。

扫描二维码关注公众号,回复: 10705765 查看本文章

分析:

求最小值的最大值,一般采用二分。

那么我们就需要判断二分过程中某个高度H是否可行。判断时,采用BFS从起点向外搜索,同时记录从起点到达该点的步数,用原始高度减去步数就可以求出洞穴的当前高度,搜索过程中保证访问的洞穴的当前高度大于等于H(因为要保证找到的H是最小值)。当发现终点可达时,高度H就可行。

具体解释见代码。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#define INF 0x3f3f3f3f
#define mst(a,num) memset(a,num,sizeof a)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define repd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
const ll mod = 1e9 + 7;
const int maxn = 500 + 5;

int n,m;
int a[maxn][maxn];
int vis[maxn][maxn];

int dir[5][2]={{0,0},{-1,0},{1,0},{0,-1},{0,1}};

bool checkpos(int x,int y){             //判断坐标是否合法
    if(x<=n&&x>=1&&y<=m&&y>=1)  return true;
    return false;
}

struct node
{
    int x,y;
    int dis;        //从起点到达该点的步数
};

queue<node> q;

bool check(int height){
    node st;
    st.x=st.y=1;
    st.dis=0;
    while(!q.empty())  q.pop();
    mst(vis,0);
    q.push(st);
    while(!q.empty()){
        node tp=q.front();
        q.pop();
        int x=tp.x,y=tp.y;
        int dis=tp.dis;
        if(vis[x][y])  continue;
        vis[x][y]=1;
        if(a[x][y]-dis>=height){                //洞穴当前高度大于等于height才做拓展
            if(x==n&&y==m)  return true;        //终点可达
            rep(i,1,4){
                int nxtx=x+dir[i][0],nxty=y+dir[i][1];
                if(checkpos(nxtx,nxty)){
                    node nxt;
                    nxt.x=nxtx;
                    nxt.y=nxty;
                    nxt.dis=dis+1;
                    q.push(nxt);
                }
            }
        }
    }
    return false;
}

int main() {
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        rep(i,1,n)
            rep(j,1,m)
                scanf("%d",&a[i][j]);
        int l=1,r=1e9,ans=-1;                   //二分范围[1,1e9],由于洞穴的高度必须大于0,才能通过,所以不能包括0
        while(l<=r){
            int mid=(l+r)/2;
            if(check(mid)){                     //如果当前高度可行,那么寻找可能的更大的可行高度
                ans=mid;
                l=mid+1;
            }
            else{                               //如果当前高度不可行,那么寻找可能的更小的可行高度
                r=mid-1;
            }
        }
        if(ans==-1)  printf("impossible\n");
        else   printf("%d\n",ans);
    }
    return 0;
}
发布了30 篇原创文章 · 获赞 5 · 访问量 900

猜你喜欢

转载自blog.csdn.net/qq_42840665/article/details/105179880