• 【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
    ", ans); 
    	return 0; 
    } 
    
  • 相关阅读:
    php1
    element ui
    webpack
    vue-router
    vue实例相关2
    vue实例相关
    js笔记2
    js笔记
    不找工作,你的简历也要更新!
    除了做测试,我们还能做些什么呢?
  • 原文地址:https://www.cnblogs.com/heyujun/p/10179259.html
Copyright © 2020-2023  润新知