​传送门​

很容易想到二分答案, 然后离散化一下, 找出上下左右最偏僻的点再判断

矩阵覆盖可以用二维的差分

#include<bits/stdc++.h>
#define N 1005
using namespace std;
int read(){int x; scanf("%d", &x); return x;}
int n, m, k;
struct Node{int x, y;}pos[N];
int x[N], y[N], Sizx, Sizy;
int mp[N][N];
bool check(int mid){
memset(mp, 0, sizeof(mp)); Sizx = 0; Sizy = 0;
memset(x, 0, sizeof(x)); memset(y, 0, sizeof(y));
for(int i=1; i<=k; i++){
x[++Sizx] = max(1, pos[i].x - mid); x[++Sizx] = min(n+1, pos[i].x + mid + 1);
y[++Sizy] = max(1, pos[i].y - mid); y[++Sizy] = min(m+1, pos[i].y + mid + 1);
} x[++Sizx] = 1; x[++Sizx] = n+1; y[++Sizy] = 1; y[++Sizy] = m+1;
sort(x+1, x+Sizx+1); Sizx = unique(x+1, x+Sizx+1) - (x+1);
sort(y+1, y+Sizy+1); Sizy = unique(y+1, y+Sizy+1) - (y+1);
for(int i=1; i<=k; i++){
int x1 = lower_bound(x+1, x+Sizx+1, max(1, pos[i].x - mid)) - x;
int x2 = lower_bound(x+1, x+Sizx+1, min(n+1, pos[i].x + mid + 1)) - x;
int y1 = lower_bound(y+1, y+Sizy+1, max(1, pos[i].y - mid)) - y;
int y2 = lower_bound(y+1, y+Sizy+1, min(m+1, pos[i].y + mid + 1)) - y;
mp[x1][y1]++; mp[x1][y2]--; mp[x2][y1]--; mp[x2][y2]++;
}
int up = 0, down = Sizx, l = Sizy, r = 0;
for(int i=1; i<Sizx; i++){
for(int j=1; j<Sizy; j++){
mp[i][j] += mp[i-1][j] + mp[i][j-1] - mp[i-1][j-1];
if(!mp[i][j]){
up = max(up, i); down = min(down, i);
l = min(l, j); r = max(r, j);
}
}
}
if(down == Sizx) return true; if(l == Sizy) return true;
down = x[down]; up = x[up+1] - 1;
l = y[l]; r = y[r+1] - 1;
if(up - down > mid * 2) return false;
if(r - l > mid * 2) return false;
return true;
}
int main(){
n = read(), m = read(), k = read();
for(int i=1; i<=k; i++){
pos[i] = (Node){read(), read()};
}
int l = 0, r = 1e9;
while(l < r){
int mid = (l+r) >> 1;
if(check(mid)) r = mid; else l = mid + 1;
} printf("%d", l); return 0;
}