博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
题解 P1034 【矩形覆盖】
阅读量:4685 次
发布时间:2019-06-09

本文共 3089 字,大约阅读时间需要 10 分钟。

题面

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

12.png

这些点可以用k个矩形(1≤k≤4)全部覆盖,矩形的边平行于坐标轴。当k=2时,可用如图二的两个矩形S1,s2覆盖,81,S2面积和为4。问题是当n个点坐标和k给出后,怎样才能使得覆盖所有点的k个矩形的面积之和为最小呢?

约定:覆盖一个点的矩形面积为0;覆盖平行于坐标轴直线上点的矩形面积也为0。各个矩形必须完全分开(边线与顶点也都不能重合)。

题意

有n个点,找k个矩形包含所有点,使k个矩形和面积和最小。

题解

这道题刚拿到手里的时候是挺棘手的,但是我们看数据范围的大小,是可以暴力枚举的,所以我们可以尝试一下暴力枚举。

建图操作

  1. maps用来存图

  2. ss用来存构建的矩形

    • 立flag来统计这种矩形是否建过

    • 数据最大是4块矩形,可以开小数组

struct maps{    int x,y;} mapp[51];struct ss{    int l,r,u,d;    bool flag;} p[5];

判断操作

  1. judge函数枚举四种不成立的情况

  2. in函数判断范围,便于书写judge函数

bool in(ss a, int x, int y){    if (x>=a.l&&x<=a.r&&y>=a.d&&y<=a.u) return 1;    return 0;}bool judge(ss a, ss b){    if (in(a,b.l,b.u)) return 1;    if (in(a,b.l,b.d)) return 1;    if (in(a,b.r,b.u)) return 1;    if (in(a,b.r,b.d)) return 1;    return 0;}

dfs操作

  1. 构建好m个矩形

  2. 计算面积和

  3. 每次存最小值

  4. 搜完结束

void dfs(int num){    int value=0;    for (int i=1; i<=m; i++)    {      if (p[i].flag)      {        for (int j=i+1; j<=m; j++)          if (judge(p[i],p[j])) return;      }      value+=(p[i].r-p[i].l)*(p[i].u-p[i].d);    }    if (value>=ans) return;    if (num>n){        ans=value;        return;    }    for (int i=1; i<=m; i++)    {        ss tmp=p[i];        if (p[i].flag==0)        {            p[i].flag=1;            p[i].l=p[i].r=mapp[num].x;            p[i].u=p[i].d=mapp[num].y;            dfs(num+1); p[i]=tmp;            break;        }        else         {            p[i].r=max(p[i].r,mapp[num].x);                         p[i].l=min(p[i].l,mapp[num].x);            p[i].u=max(p[i].u,mapp[num].y);             p[i].d=min(p[i].d,mapp[num].y);            dfs(num+1);            p[i]=tmp;        }        }}

代码

#include
#include
using namespace std;struct maps{ int x,y;} mapp[51];struct ss{ int l,r,u,d; bool flag;} p[5];int n,m,ans=0x7f7f7f7f;bool in(ss a, int x, int y){ if (x>=a.l&&x<=a.r&&y>=a.d&&y<=a.u) return 1; return 0;}bool judge(ss a, ss b){ if (in(a,b.l,b.u)) return 1; if (in(a,b.l,b.d)) return 1; if (in(a,b.r,b.u)) return 1; if (in(a,b.r,b.d)) return 1; return 0;}void dfs(int num){ int value=0; for (int i=1; i<=m; i++) { if (p[i].flag) { for (int j=i+1; j<=m; j++) if (judge(p[i],p[j])) return; } value+=(p[i].r-p[i].l)*(p[i].u-p[i].d); } if (value>=ans) return; if (num>n){ ans=value; return; } for (int i=1; i<=m; i++) { ss tmp=p[i]; if (p[i].flag==0) { p[i].flag=1; p[i].l=p[i].r=mapp[num].x; p[i].u=p[i].d=mapp[num].y; dfs(num+1); p[i]=tmp; break; } else { p[i].r=max(p[i].r,mapp[num].x); p[i].l=min(p[i].l,mapp[num].x); p[i].u=max(p[i].u,mapp[num].y); p[i].d=min(p[i].d,mapp[num].y); dfs(num+1); p[i]=tmp; } }}int main(void){ scanf("%d%d",&n,&m); for (int i=1; i<=n; i++) scanf("%d%d",&mapp[i].x,&mapp[i].y); dfs(1); printf("%d",ans); return 0;}

转载于:https://www.cnblogs.com/Chicago/p/9920720.html

你可能感兴趣的文章
2018-2019-1 20165301 《信息安全系统设计基础》第五周学习总结
查看>>
EF多个表映射
查看>>
J2EE项目集成SAP的BO报表
查看>>
SpringBoot常用属性配置
查看>>
linux sdcv命令
查看>>
BZOJ4836: [Lydsy1704月赛]二元运算【分治FFT】【卡常(没卡过)】
查看>>
MPU6050开发 -- 数据分析(转)
查看>>
springmvc入门详解
查看>>
用户名、密码等15个常用的js正则表达式
查看>>
对比多层字典是否相同函数
查看>>
你在哪编程?你的程序原料是什么?
查看>>
ehcache 简介
查看>>
java uuid 例子
查看>>
linux zip 压缩密码
查看>>
【SICP练习】26 练习1.32
查看>>
Centos下安装破解Jira7的操作记录
查看>>
Python AES_ECB_PKCS5加密代码
查看>>
SpringBoot--外部配置
查看>>
C#中的线程三 (结合ProgressBar学习Control.BeginInvoke)
查看>>
sqlserver工作日常使用sql--持续完善中
查看>>