zoukankan      html  css  js  c++  java
  • BZOJ 1052: [HAOI2007]覆盖问题

    BZOJ 1052: [HAOI2007]覆盖问题

    题意:给定平面上横纵坐标在-1e9~1e9内的20000个整数点的坐标,用三个大小相同边平行于坐标轴的正方形覆盖(在边界上的也算),问正方形的边长最小为多少?(整数)

    思路:构造一个覆盖所有点的矩形正方形的端点即为矩形的一角,这样枚举四个角的两个正方形,二分最大长度,看剩下的点是否能被第三个正方形覆盖。
    ps:构造矩形的思想是看了题解才想到的。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<stdlib.h>
    #include<time.h>
    using namespace std;
    #define rep(i,n) for((i) = 0;i < n;i++)
    struct Point{
        int x[20200], y[20200],top;
    }a;
    const int inf = 1000000000;
    void cut(Point &a,int x1,int y1,int x2,int y2)
    {
        Point b;
        b.top = a.top;
        for(int k = 1;k <= a.top;k++)
            b.x[k] = a.x[k],b.y[k] = a.y[k];
        a.top = 0;
        for(int i = 1;i <= b.top;i++)
            if(b.x[i] < x1 || b.x[i] > x2 || b.y[i] < y1 || b.y[i] > y2){
                a.x[++a.top] = b.x[i];
                a.y[a.top] = b.y[i];
            }
    }
    void solve(Point &a,int id,int mid)
    {
        int x1 = inf ,x2 = -inf ,y1 = inf ,y2 = -inf;
        for(int k = 1;k <= a.top;k++){
            x1 = min(x1,a.x[k]);x2 = max(x2,a.x[k]);
            y1 = min(y1,a.y[k]);y2 = max(y2,a.y[k]);
        }
        if(id == 1)
            cut(a,x1,y1,x1+mid,y1+mid);
        if(id == 2)
            cut(a,x1,y2-mid,x1+mid,y2);
        if(id == 3)
            cut(a,x2-mid,y1,x2,y1+mid);
        if(id == 4)
            cut(a,x2-mid,y2-mid,x2,y2);
    }
    bool judge(int mid)
    {
        Point b;
        for(int i = 1;i <= 4;i++){
            for(int j = 1;j <= 4;j++){
                b.top = a.top;
                for(int k = 1;k <= b.top;k++)
                    b.x[k] = a.x[k],b.y[k] = a.y[k];
                solve(b,i,mid);
                solve(b,j,mid);    //可以只是一个正方形;
                int x1 = inf ,x2 = -inf ,y1 = inf ,y2 = -inf;
                for(int k = 1;k <= b.top;k++){
                    x1 = min(x1,b.x[k]);x2 = max(x2,b.x[k]);
                    y1 = min(y1,b.y[k]);y2 = max(y2,b.y[k]);
                }
                if(x2 - x1 <= mid && y2 - y1 <= mid) return true;
            }
        }
        return false;
    }
    int main()
    {
        int n,xx,yy;
        cin>>n;
        a.top = n;
        for(int i = 1;i <= n;i++){
            scanf("%d%d",&xx,&yy);
            a.x[i] = xx;
            a.y[i] = yy;
        }
        int l = 0,r = inf,ans;
        while(l <= r){
            int mid = (l + r) >> 1;
            if(judge(mid))
                ans = mid,r = mid - 1;
            else l = mid + 1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    C++——多态
    C++——继承
    PAT1002 A+B for Polynomials
    PAT1001-A+B Format
    C++——运算符重载(下)
    图像处理与Python实现(岳亚伟)笔记二——彩色图像处理
    图像处理与Python实现(岳亚伟)笔记一
    827. Making A Large Island
    995. Minimum Number of K Consecutive Bit Flips (2021/2/18每日一题)
    685. Redundant Connection II (LeetCode 刷题笔记)
  • 原文地址:https://www.cnblogs.com/hxer/p/5185136.html
Copyright © 2011-2022 走看看