链接:https://ac.nowcoder.com/acm/problem/213267
来源:牛客网
题目描述
众所周知,浙农林是一条河。
由于浙江农林大学的特殊地形,当你在下雨后漫步在农林大路上的时候
难免会出现一脚踩进一个水坑的情况的情况。而农农非常不喜欢踩到水坑的感觉,
请你帮忙设计一个程序来帮助农农判断他能否在不踩入水坑的情况下回到
寝室。
已知,浙江农林大学可以表示为一个 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)
思路
原本打算写dp找到点高度最高的路,发现有那种可以绕开走的数据会wa
后来清题的时候发现可以用二分找这个最大值配合bfs,真的妙啊。
代码
#include <bits/stdc++.h>
typedef unsigned long long ll;
const ll mod = 9999999967;
using namespace std;
namespace fastIO {
inline void input(int& res) {
char c = getchar();res = 0;int f = 1;
while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
res = f ? res : -res;
}
inline ll qpow(ll a, ll b) {
ll ans = 1, base = a;
while (b) {
if (b & 1) ans = (ans * base % mod +mod )%mod;
base = (base * base % mod + mod)%mod;
b >>= 1;
}
return ans;
}
}
using namespace fastIO;
const int N = 1e3+5;
const double esp = 1e-5;
int a[N][N],vis[N][N];
int n,q,x,maxx;
struct node{
int x;
int y;
int minn;
};
int dir[4][2]={{1,0},{0,1},{0,-1},{-1,0}};
bool bfs(int x){
queue<node> q;
memset(vis,0,sizeof(vis));
if(x>a[1][1]) return 0;
vis[1][1]=1;
q.push(node{1,1,a[1][1]});
while(!q.empty()){
node t=q.front();
q.pop();
for(int i=0;i<4;i++){
int nx=t.x+dir[i][0];
int ny=t.y+dir[i][1];
if(a[nx][ny]>=x&&vis[nx][ny]==0&&nx>0&&ny>0&&nx<=n&&ny<=n){
q.push(node{nx,ny,min(t.minn,a[nx][ny])});
vis[nx][ny]=1;
}
}
}
//cout<<x<<" "<<vis[n][n]<<endl;
if(vis[n][n]) return true;
return false;
}
int main(){
input(n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
input(a[i][j]);
}
}
int l=1,r=1e5;
while(l<=r){
int mid=(l+r)>>1;
if(bfs(mid)){
l=mid+1;
maxx=mid;
}
else r=mid-1;
}
//cout<<maxx<<endl;
input(q);
for(int i=1;i<=q;i++){
input(x);
if(x<=maxx) puts("Wuhu");
else puts("Hmmm");
}
return 0;
}
/*
4
5 2 3 2
4 5 3 4
2 1 4 5
3 3 3 3
2
1
5
*/