浙江农林大学第十九届程序设计竞赛暨天梯赛选拔赛-M 灾难预警
链接:https://ac.nowcoder.com/acm/contest/7872/M
来源:牛客网
题目描述
众所周知,浙农林是一条河。
由于浙江农林大学的特殊地形,当你在下雨后漫步在农林大路上的时候
难免会出现一脚踩进一个水坑的情况的情况。而农农非常不喜欢踩到水坑的感觉,
请你帮忙设计一个程序来帮助农农判断他能否在不踩入水坑的情况下回到
寝室。
已知,浙江农林大学可以表示为一个 N * N 的矩阵。
对于每个位置有一个海拔数据 h[i][j],当水位高度大于 h[i][j] 的时候,
这个位置就会形成一个水坑。
农农现在的坐标是 (1, 1), 他的宿舍位于 (n, n).
农农只可以沿着上下左右四个方向走。
假如农农现在位于 (2, 2)那么在不考虑水位的情况下,他可以去的地方有
(1, 2),(2,1), (3, 2) ,(2, 3)
输入描述:
N (表示矩阵大小)
接下来 N 行为一个 N * N 的矩阵 h
Q (表示询问数量)
接下来 Q 行每行一个数字,表示当前水位 X
1 <= N <= 1000
1 <= h[i][j] <= 100000
1 <= X <= 100000
1 <= Q <= 100000
输出描述:
共 Q 行,表示在对应水位下,农农能否在不踩入水坑的情况下
回到寝室, 如果农农可以回到寝室,请你输出“Wuhu”, 反之请输出
“Hmmm”
示例1
输入
复制
4
5 2 3 2
4 5 3 4
2 1 4 5
3 3 3 3
2
1
5
输出
复制
Wuhu
Hmmm
说明
对于第一次询问,没有任何一个位置形成水坑,所以农农可以从(1, 1)走到(4, 4)
对于第二次询问 高度小于 5 的位置形成了水坑,其中包括目的地 (4, 4)所以农农无法在
不踩到水坑的情况下走到(4, 4)
***题目大意***本题给了一个图,实际上是找一条可以从图左上角走到右下角的路,使得这条路所经过的每个点的权值的最小值最大。
***思路***本题在比赛时我没有马上想出来,一开始打了一个原始的dfs找这条路,然后T掉了,赛后看了别人的代码才恍然大悟,发现只要用二分把水位二分一下,然后每次跑一遍dfs,看看是否能走到,最后就可以快速求出可以承受的最高水位。然后每次直接判定一下就好了。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[1007][1007];
int vis[1007][1007];
int zou[4][2]={0,1,0,-1,-1,0,1,0};
int n;
void dfs(int x,int y,int low)
{
vis[x][y]=1;
if(x==n&&y==n)
{
return;
}
int maxn=0;
for(int i=0;i<4;i++)
{
int xx=x+zou[i][0];
int yy=y+zou[i][1];
if(xx<=0||xx>n||yy<=0||yy>n||vis[xx][yy]==1||a[xx][yy]<low)continue;
dfs(xx,yy,low);
if(vis[n][n]==1)return ;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
int l=1,r=100000,mid;
while(l<r)
{
memset(vis,0,sizeof(vis));
mid=(l+r)>>1;
if(a[1][1]>=mid)dfs(1,1,mid);
if(vis[n][n]==1){
l=mid+1;
}else
{
r=mid;
}
}
int q;
scanf("%d",&q);
while(q--)
{
int x;
scanf("%d",&x);
if(x>=l)
{
printf("Hmmm\n");
}else
{
printf("Wuhu\n");
}
}
return 0;
}