• 洛谷 P1034 矩形覆盖


    题目描述

    在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示。例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4(0,7),见图一。

    这些点可以用 k 个矩形(1<=k<=4)全部覆盖,矩形的边平行于坐标轴。当 k=2 时,可用如图二的两个矩形 sl,s2 覆盖,s1,s2 面积和为 4。问题是当 n 个点坐标和 k 给出后,怎样才能使得覆盖所有点的 k 个矩形的面积之和为最小呢。约定:覆盖一个点的矩形面积为 0;覆盖平行于坐标轴直线上点的矩形面积也为0。各个矩形必须完全分开(边线与顶点也都不能重合)。

    输入输出格式

    输入格式:

     

    n k xl y1 x2 y2 ... ...

    xn yn (0<=xi,yi<=500)

     

    输出格式:

     

    输出至屏幕。格式为:

    一个整数,即满足条件的最小的矩形面积之和。

     

    输入输出样例

    输入样例#1:
    4 2
    1 1
    2 2
    3 6
    0 7
    
    输出样例#1:
    4
    思路:深搜,枚举每个点放在哪个矩形中
    吐槽:(╯‵□′)╯︵┻━┻,cogs上第6组数据竟然是错误的,害我调试了辣么久。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,k,ans=0x7f7f7f7f,val;
    struct nond{
        int x,y;
    }v[60];
    struct none{
        int l,r,u,d; //记录这个矩形的四极。 
        bool falg;    //判断这个矩形内有没有点 
    }f[5];
    int judge(int i,int j){
        if(f[i].l<=f[j].l&&f[i].r>=f[j].l&&f[i].d>=f[j].d&&f[i].u<=f[j].d)    return 1;
        if(f[i].l<=f[j].r&&f[i].r>=f[j].r&&f[i].d>=f[j].d&&f[i].u<=f[j].d)    return 1;
        if(f[i].l<=f[j].l&&f[i].r>=f[j].l&&f[i].d>=f[j].u&&f[i].u<=f[j].u)    return 1;
        if(f[i].l<=f[j].r&&f[i].r>=f[j].r&&f[i].d>=f[j].u&&f[i].u<=f[j].u)    return 1;
        return 0;
    }
    void dfs(int num){
        val=0;
        for(int i=1;i<=k;i++){
            if(f[i].falg)
                for(int j=i+1;j<=k;j++)
                    if(f[j].falg&&judge(i,j))    return ;
            val+=(f[i].r-f[i].l)*(f[i].d-f[i].u);//统计到目前为止的矩形的面积和。 
        }
        if(val>=ans)    return;
        if(num>n){
            ans=val;
            return ;
        }
        for(int i=1;i<=k;i++){
            none tmp=f[i];
            if(!f[i].falg){
                f[i].falg=1;
                f[i].l=f[i].r=v[num].x;
                f[i].d=f[i].u=v[num].y;
                dfs(num+1);
                f[i]=tmp;
            }
            else{
                f[i].l=min(f[i].l,v[num].x);
                f[i].r=max(f[i].r,v[num].x);
                f[i].u=min(f[i].u,v[num].y);
                f[i].d=max(f[i].d,v[num].y);
                dfs(num+1);
                f[i]=tmp;
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
            scanf("%d%d",&v[i].x,&v[i].y);
        dfs(1);
        cout<<ans;
    }
     
    细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。 雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。
  • 相关阅读:
    Windows系统环境变量path优先级测试报告
    URI和URL的区别
    智能引导式报错(Class file name must end with .class)
    【Algorithm】冒泡排序
    【C语言】练习2-9
    【C语言】练习2-8
    【C语言】练习2-1
    【C语言】练习1-23
    【C语言】练习1-22
    【C语言】练习1-21
  • 原文地址:https://www.cnblogs.com/cangT-Tlan/p/7466067.html
Copyright © 2020-2023  润新知