CODEVS 1101 矩形覆盖 NOIP2002

题目大意

在平面上有 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的情况)

分析

这个其实暴搜就可以了。
按照每个点,搜覆盖它的矩形。
这里比较有趣的一点是,我原以为把点先排序后再搜,这样会快一些。
但是并不,甚至还TLE了!可能是因为不排序时,点比较分散,dfs的时候能很快找到不符合条件的情况。

代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 60, K = 10, inf = 1<<30;
struct NODE { //这里储存矩形。 lx和ly是矩形左下角的坐标,rx和ry是右上角的
    int lx, ly, rx, ry;
}s[K]; 
struct Point {
    int x, y;
}e[N];
int n, k, ans = inf;

bool cmp(Point a, Point b) {
    if(a.x == b.x) return a.y < b.y;
    return a.x > b.x;
}

int getS() {    //矩形面积
    int S = 0;
    for(int i = 1; i <= k; i++) {
        S += (s[i].rx - s[i].lx) * (s[i].ry - s[i].ly);
    }
    return S;
}

bool judge(NODE a, NODE b) { //判断两个矩形是否合法
    if(a.lx == inf || a.ly == inf || a.rx == -inf || a.ry == -inf)
        return 1;
    if(b.lx == inf || b.ly == inf || b.rx == -inf || b.ry == -inf)
        return 1;
    if(a.lx > b.rx || a.ly > b.ry)
        return 1;
    if(b.lx > a.rx || b.ly > a.ry)
        return 1;
    return 0;
}

bool check() {
    int flag = 1;
    for(int i = 1; i <= k; i++) {
        for(int j = i+1; j <= k; j++) {
            flag = judge(s[i], s[j]);
        }
    }
    return flag;
}

void dfs(int v) {
    if(v == n+1) {
        ans = min(ans, getS());
        return ;
    }
    for(int i = 1; i <= k; i++) {
        NODE tmp = s[i];
        s[i].lx = min(s[i].lx, e[v].x);
        s[i].ly = min(s[i].ly, e[v].y);
        s[i].rx = max(s[i].rx, e[v].x);
        s[i].ry = max(s[i].ry, e[v].y);
        if(check() && getS() < ans)
            dfs(v+1);
        s[i] = tmp;
    }
}

int main() {
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++)
        scanf("%d%d", &e[i].x, &e[i].y);
//  sort(e+1, e+1+n, cmp);
    for(int i = 1; i <= k; i++) {
        s[i].lx = s[i].ly = inf;
        s[i].rx = s[i].ry = -inf;
    }
    dfs(1);
    printf("%d\n", ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++语言画矩形 "_AFXDLL" "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\Test.rc"" Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8A.tmp" with contents [ /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/Test.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\MainFrm.cpp" "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\Picdlg.cpp" "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\Test.cpp" "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\TestDoc.cpp" "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\TestView.cpp" ] Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8A.tmp" Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8B.tmp" with contents [ /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /Fp"Debug/Test.pch" /Yc"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c "E:\E03教学\2011下半年\图形学\计算机图形学基础教程(Visual C++版)\第五章\案例9-二维基本几何变换算法\StdAfx.cpp" ] Creating command line "cl.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8B.tmp" Creating temporary file "C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8C.tmp" with contents [ /nologo /subsystem:windows /incremental:yes /pdb:"Debug/Test.pdb" /debug /machine:I386 /out:"Debug/Test.exe" /pdbtype:sept ".\Debug\MainFrm.obj" ".\Debug\Picdlg.obj" ".\Debug\StdAfx.obj" ".\Debug\Test.obj" ".\Debug\TestDoc.obj" ".\Debug\TestView.obj" ".\Debug\Test.res" ] Creating command line "link.exe @C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\RSP8C.tmp" <h3>Output Window</h3> Compiling resources... Compiling... StdAfx.cpp Compiling... MainFrm.cpp Picdlg.cpp Test.cpp TestDoc.cpp TestView.cpp Generating Code... Linking...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值