CF845E Fire in the City [二分+差分]

传送门

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

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

#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;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值