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

    给定平面上若干点,用三个等大的正方形去覆盖(在边界上也算被覆盖),边平行于坐标轴,求最小边长。(n leq 20000)

    Solution

    为什么是三个矩形?

    • 对于 (k) 个矩形的覆盖方案,至少各有一个矩形与四条边界重合

    而当 (kleq3) 时,如果每个矩形都恰好只沾了一条边界,那么与上述引理矛盾,因此

    • 对于 (k leq 3) 个矩形的覆盖方案,至少有一个矩形与边界矩形的一个角重合

    因此,考虑二分,检验答案时,我们只需要枚举下一个矩形放在哪个角上,然后算出去掉这些点后的边界,并递归做下去即可

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    
    const int N = 20005;
    int n,x[N],y[N],u[N],a;
    
    int dfs(int k) {
        int xl=1e9,xr=-1e9,yl=1e9,yr=-1e9;
        for(int i=1;i<=n;i++) if(u[i]==0) {
            xl=min(xl,x[i]);
            yl=min(yl,y[i]);
            xr=max(xr,x[i]);
            yr=max(yr,y[i]);
        }
        if(k==1) {
            if(xr-xl<=a && yr-yl<=a) return 1;
            return 0;
        }
        else {
            int tmp=0;
            vector <int> v;
            for(int i=1;i<=n;i++) {
                if(xl<=x[i] && x[i]<=xl+a && yl<=y[i] && y[i]<=yl+a && u[i]==0) {
                    v.push_back(i);
                    u[i]=1;
                }
            }
            tmp = dfs(k-1);
            for(int i=0;i<v.size();i++) u[v[i]]=0;
            v.clear();
            if(tmp) return 1;
            for(int i=1;i<=n;i++) {
                if(xl<=x[i] && x[i]<=xl+a && yr-a<=y[i] && y[i]<=yr && u[i]==0) {
                    v.push_back(i);
                    u[i]=1;
                }
            }
            tmp = dfs(k-1);
            for(int i=0;i<v.size();i++) u[v[i]]=0;
            v.clear();
            if(tmp) return 1;
            for(int i=1;i<=n;i++) {
                if(xr-a<=x[i] && x[i]<=xr && yl<=y[i] && y[i]<=yl+a && u[i]==0) {
                    v.push_back(i);
                    u[i]=1;
                }
            }
            tmp = dfs(k-1);
            for(int i=0;i<v.size();i++) u[v[i]]=0;
            v.clear();
            if(tmp) return 1;
            for(int i=1;i<=n;i++) {
                if(xr-a<=x[i] && x[i]<=xr && yr-a<=y[i] && y[i]<=yr && u[i]==0) {
                    v.push_back(i);
                    u[i]=1;
                }
            }
            tmp = dfs(k-1);
            for(int i=0;i<v.size();i++) u[v[i]]=0;
            v.clear();
            if(tmp) return 1;
        }
        return 0;
    }
    
    int check() {
        for(int i=1;i<=n;i++) u[i]=0;
        int tmp=dfs(3);
        return tmp;
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=1;i<=n;i++) cin>>x[i]>>y[i];
        int l=0,r=2e9;
        while(l<r) {
            a=(l+r)/2;
            if(check()) r=a;
            else l=a+1;
        }
        cout<<l;
    }
    
    
  • 相关阅读:
    洛谷八连测R7 nzhtl1477-我回来了
    String中的equals方法原理分析
    Java线程
    Spring配置日志级别报红:Caused by: org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'logging.level' to java.util.Map<java.lang.String
    # SpringMVC跨服务器上传文件出现的问题
    使用Maven创建Spring-web项目的基本流程
    Maven的下载与安装(环境变量的配置)
    eNSP的安装(附链接)
    数据库分页操作
    Sql语句占位符?的使用
  • 原文地址:https://www.cnblogs.com/mollnn/p/12381768.html
Copyright © 2011-2022 走看看