P1902 刺杀大使 题解
题目
题目传送门。
题解
思路
这一题我们可以使用二分答案+BFS的解法。
我们二分整个部队受到的伤害最小值\(x\),每次使用\(check(int\ x)\)函数用于检验是否可以在最小值为\(x\)的情况下到达第\(n\)行。
随后就是BFS的板子了,从(1,1)开始BFS,每次记录一下\(vis[x][y]=1\)(防止重复搜索,避免MLE风险),如果搜索到了第\(n\)行则直接返回true,否则在循环结束时返回false。
在二分循环内根据\(check\)的返回值进行相对应的\(l\)和\(r\)的调整即可。
代码
#include<bits/stdc++.h>
#define endl '\n'using namespace std;int n,m,p[1005][1005];
int fx[5]={0,0,1,0,-1};
int fy[5]={0,1,0,-1,0};
bool vis[1005][1005]={0};
inline bool check(int t){memset(vis,0,sizeof(vis));int mnp=1005;pair<int,int> start={1,1};queue<pair<int,int>> q;q.push(start);vis[1][1]=1;while(!q.empty()){start=q.front();q.pop();int x=start.first,y=start.second;int tx,ty;if(x==n){return 1;}for(int i=1;i<=4;i++){tx=x+fx[i];ty=y+fy[i];if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&!vis[tx][ty]&&p[tx][ty]<=t){vis[tx][ty]=1;q.push({tx,ty});}}} return 0;
}
int main(){cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>p[i][j];}}int l=0,r=1001;while(l+1<r){int mid=l+((r-l)>>1);if(check(mid)) r=mid;else l=mid;}cout<<r<<endl;return 0;
}