【BZOJ1052】[HAOI2007]覆盖问题

【BZOJ1052】[HAOI2007]覆盖问题

题面

bzoj

洛谷

题解

二分答案是显然的。

算一下包含所有的点的最小矩形的范围\((x1,y1)\)\((x2,y2)\)

贪心思考一下肯定是把塑料薄膜其中一个角放在此矩形上的

然后\(dfs\)判一下即可

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring> 
#include <cmath> 
#include <algorithm>
using namespace std; 
inline int gi() {
	register int data = 0, w = 1;
	register char ch = 0;
	while (!isdigit(ch) && ch != '-') ch = getchar(); 
	if (ch == '-') w = -1, ch = getchar(); 
	while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
	return w * data; 
} 
void chkmax(int &x, int y) { if (x < y) x = y; } 
void chkmin(int &x, int y) { if (x > y) x = y; } 
const int MAX_N = 20005; 
int N, vis[MAX_N]; 
pair<int, int> p[MAX_N]; 
#define x first 
#define y second
void cover(int x1, int x2, int y1, int y2, int id) { 
	for (int i = 1; i <= N; i++) 
		if (!vis[i] && x1 <= p[i].x && p[i].x <= x2 && y1 <= p[i].y && p[i].y <= y2) 
			vis[i] = id; 
} 
void uncover(int id) { for (int i = 1; i <= N; i++) if (vis[i] == id) vis[i] = 0; } 
bool dfs(int tot, int L) { 
	int _x[2], _y[2]; _x[0] = _y[0] = 2e9, _x[1] = _y[1] = -2e9; 
	for (int i = 1; i <= N; i++)
		if (!vis[i])
			chkmin(_x[0], p[i].x), chkmax(_x[1], p[i].x), chkmin(_y[0], p[i].y), chkmax(_y[1], p[i].y);
	if (max(_x[1] - _x[0], _y[1] - _y[0]) <= L) return 1;
	if (tot == 3) return 0; 
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 2; j++) {
			if (i == 0) {
				if (j == 0) cover(_x[0], _x[0] + L, _y[0], _y[0] + L, tot); 
				else cover(_x[0], _x[0] + L, _y[1] - L, _y[1], tot); 
			} else { 
				if (j == 0) cover(_x[1] - L, _x[1], _y[0], _y[0] + L, tot); 
				else cover(_x[1] - L, _x[1], _y[1] - L, _y[1], tot); 
			}
			if (dfs(tot + 1, L)) return 1; 
			uncover(tot); 
		} 
    return 0; 
}
bool check(int L) {
	memset(vis, 0, sizeof(vis));
	return dfs(1, L); 
} 
int main () {
	N = gi(); for (int i = 1; i <= N; i++) p[i].x = gi(), p[i].y = gi();
	int l = 0, r = 2e9, ans = 2e9;
	while (l <= r) {
		int mid = ((long long)l + r) >> 1ll;
		if (check(mid)) r = mid - 1, ans = mid;
		else l = mid + 1; 
	}
	printf("%d\n", ans); 
	return 0; 
} 
posted @ 2018-12-26 15:12  heyujun  阅读(313)  评论(0编辑  收藏  举报