zoukankan      html  css  js  c++  java
  • 矩形覆盖(codevs 1101)

    题目描述 Description

    在平面上有 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。各个矩形必须完全分开(边线与顶点也都不能重合)。

    输入描述 Input Description

    n k
    xl y1

    x2 y2
    ... ...
    xn yn (0<=xi,yi<=500)

    输出描述 Output Description

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

    样例输入 Sample Input

    4 2
    1 1
    2 2
    3 6
    0 7

    样例输出 Sample Output

    4

    数据范围及提示 Data Size & Hint

    k<4

    官方是k<=4,但是标程解法在k=4时是有反例的。官方的数据也没有出现k=4的情况

    /*
      由于k<=3,所以可以分着做 
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #define N 52
    #define INF 10000000
    using namespace std;
    int n,m;
    struct node
    {
        int x,y;
    };node a[N];
    bool cmp1(const node&s1,const node&s2)
    {
        return s1.x<s2.x;
    }
    bool cmp2(const node&s1,const node&s2)
    {
        return s1.y<s2.y;
    }
    int work1(int s,int t)
    {
        int mnx=INF,mxx=0,mny=INF,mxy=0;
        for(int i=s;i<=t;i++)
        {
              mnx=min(mnx,a[i].x);mxx=max(mxx,a[i].x);
              mny=min(mny,a[i].y);mxy=max(mxy,a[i].y);
        }
        return (mxx-mnx)*(mxy-mny);
    }
    int work2(int s,int t)
    {
        int minn=INF;
        sort(a+s,a+t+1,cmp1);//从左向右分 
        for(int i=s+1;i<=t-2;i++)
          if(a[i].x!=a[i+1].x)
            minn=min(minn,work1(s,i)+work1(i+1,t));
        sort(a+s,a+t+1,cmp2);//从上向下分
        for(int i=s+1;i<=t-2;i++) 
          if(a[i].y!=a[i+1].y)
            minn=min(minn,work1(s,i)+work1(i+1,t));
        return minn;
    }
    int work3(int s,int t)
    {
        int minn=INF;
        sort(a+s,a+t+1,cmp1);
        for(int i=s+1;i<=t-4;i++)
          if(a[i].x!=a[i+1].x)
            minn=min(minn,work1(s,i)+work2(i+1,t));
        for(int i=s+3;i<=t-2;i++)
          if(a[i].y!=a[i+1].y)
            minn=min(minn,work2(s,i)+work1(i+1,t));
        sort(a+s,a+t+1,cmp2);
        for(int i=s+1;i<=t-4;i++)
          if(a[i].x!=a[i+1].x)
            minn=min(minn,work1(s,i)+work2(i+1,t));
        for(int i=s+3;i<=t-2;i++)
          if(a[i].y!=a[i+1].y)
            minn=min(minn,work2(s,i)+work1(i+1,t));
        return minn;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
          scanf("%d%d",&a[i].x,&a[i].y);
        if(m==1)printf("%d",work1(1,n));
        if(m==2)printf("%d",work2(1,n));
        if(m==3)printf("%d",work3(1,n));
        return 0;
    }
    View Code
  • 相关阅读:
    ISS6 WEB服务器不能访问 grf 报表模板文件的问题
    c# 读取记事本txt文档到DataTable中
    C# 泛型LIST转DataTable
    sql 查出一张表中重复的所有记录数据
    Coolite中GridPanel真实分页(储存过程方式)
    SQL对Xml字段的操作
    反射和特性 自定义转换datatable为强类型集合
    LINQ TO SQL 并发控制
    AS3 加载文件
    使ASP.NET网站Forms验证可以指定多个登录页面
  • 原文地址:https://www.cnblogs.com/harden/p/5931371.html
Copyright © 2011-2022 走看看