好题!!!!
这题完美的结合了我前段时间的学习
这个题题意让我们求在能够完成刺杀任务前提下的伤害的最小值是多少
而伤害是经过的格子的最大值,所以就是变为了求最大值的最小值,就可以二分答案了
并且题目要求经历的格子可以是四个方向,而且是要到达最后一层就可以了,并不需要到达某个点
汇集了二分答案+flood fill
// Problem: P1902 刺杀大使
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1902
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Code by: ING__
//
// Powered by CP Editor (https://cpeditor.org)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return
#define Endl "\n"
#define endl "\n"
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int a[1010][1010];
int vis[1010][1010];
int n, m;
bool check(int hr){
queue<PII> q;
memset(vis, 0, sizeof(vis));
q.push({1, 1});
vis[1][1] = 1;
while(!q.empty()){
PII f = q.front();
q.pop();
for(int i = 0; i < 4; i++){
int nx = f.x + dx[i];
int ny = f.y + dy[i];
if(nx < 1 || nx > n || ny < 1 || ny > m || a[nx][ny] > hr)
continue;
if(vis[nx][ny]) continue;
if(nx == n) return 1;
vis[nx][ny] = 1;
q.push({nx, ny});
}
}
return 0;
}
int main(){
cin >> n >> m;
int l = 0;
int r = -1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
scanf("%d",a[i] + j);
r = max(r, a[i][j]);
}
}
while(l < r){
int mid = (l + r) >> 1;
if(check(mid)){
r = mid;
}
else{
l = mid + 1;
}
}
cout << r;
re 0;
}
722

被折叠的 条评论
为什么被折叠?



