CF1408D Searchlights

CF1408D Searchlights

注意到所有海盗有三种方式摆脱所有探照灯的控制:

1、一直向上走

2、一直向右走

3、向上走到某点后一直向右走

前两种比较好处理。对于第 \(3\) 种,不难发现只有当全局中点在灯的边界线上才会影响答案(但可能不走到边界线上更优)。这样的边界线最多 \(2000\) 条,所以我们可以先处理出每个海盗到每条边界线的距离 \(d\),将其走到此处还需要向右走才能走出去的步数记为 \(f_d\)。设当前向上走了 \(i\) 步,则答案就是 \(\min (i + \max f_i)\)

注意倒着扫描边界线并且先更新 \(f_d\),这样才能包括未走到边界线上的情况。最后更新答案。

时间复杂度为 \(O(nm)\)

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l); i <= (r); ++ i)
#define G(i,r,l) for(int i(r); i >= (l); -- i)
#define pii pair<int, int>
#define mp make_pair
#define fi first
#define se second
using namespace std;
using ll = long long;
const int N = 3000;
const int MAXN = 1e6;
int f[1005000];
int n, m, mx, ans = 0, nw;
int a[N], b[N], c[N], d[N];
signed main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> m;
	F(i, 1, n) cin >> a[i] >> b[i];
	F(i, 1, m) cin >> c[i] >> d[i];
	F(i, 1, n){
		F(j, 1, m){
			if(a[i] <= c[j] && b[i] <= d[j]){
				mx = max(mx, d[j] - b[i]);
				f[d[j] - b[i]] = max(f[d[j] - b[i]], c[j] - a[i] + 1);
			}
		}
	}
	ans = mx + 1;
//	cout << ans << '\n'; 
	G(i, mx, 0){
		nw = max(nw, f[i]);
		ans = min(ans, nw + i);
	}
	cout << ans << '\n';
	return fflush(0), 0;
}
posted @ 2025-08-13 17:48  superl61  阅读(5)  评论(0)    收藏  举报