题面

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

这些点可以用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<cstdio>
#include<iostream>
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;
}

题解 P1034 【矩形覆盖】的更多相关文章

  1. 洛谷P1034 矩形覆盖

    P1034 矩形覆盖 题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4( ...

  2. 洛谷 P1034 矩形覆盖

    P1034 矩形覆盖 题目描述 在平面上有nn个点(n \le 50n≤50),每个点用一对整数坐标表示.例如:当 n=4n=4 时,44个点的坐标分另为:p_1p1​(1,11,1),p_2p2​( ...

  3. 洛谷 - P1034 - 矩形覆盖 - dfs

    https://www.luogu.org/problemnew/show/P1034 可能是数据太水了瞎搞都可以过. 判断两个平行于坐标轴的矩形相交(含顶点与边相交)的代码一并附上. 记得这里的xy ...

  4. [NOIP2002] 提高组 洛谷P1034 矩形覆盖

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

  5. 洛谷——P1034 矩形覆盖

    https://www.luogu.org/problem/show?pid=1034 题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的 ...

  6. P1034 矩形覆盖

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

  7. luoguP1034 矩形覆盖 x

    P1034 矩形覆盖 题目描述 在平面上有 n 个点(n <= 50),每个点用一对整数坐标表示.例如:当 n=4 时,4个点的坐标分另为:p1(1,1),p2(2,2),p3(3,6),P4( ...

  8. C#版 - 剑指offer 面试题9:斐波那契数列及其变形(跳台阶、矩形覆盖) 题解

    面试题9:斐波那契数列及其变形(跳台阶.矩形覆盖) 提交网址: http://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tp ...

  9. 【旋转卡壳+凸包】BZOJ1185:[HNOI2007]最小矩形覆盖

    1185: [HNOI2007]最小矩形覆盖 Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 1945  Solve ...

  10. TZOJ 2392 Bounding box(正n边形三点求最小矩形覆盖面积)

    描述 The Archeologists of the Current Millenium (ACM) now and then discover ancient artifacts located ...

随机推荐

  1. 使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件

    写在前面 之前写过一篇关于vue实现dialog会话框组件的文章http://www.cnblogs.com/fozero/p/8546883.html, 讲到了如何实现一个vue对话框组件,其中涉及 ...

  2. sscanf函数详解 & 查找文件字符串

    1. sscanf函数 sscanf() - 从一个字符串中读进与指定格式相符的数据. 1.1 函数原型 int scanf(const char *format, ...); int fscanf( ...

  3. C#图片文字识别

    图片识别的技术到几天已经很成熟了,只是相关的资料很少,为了方便在此汇总一下(C#实现),方便需要的朋友查阅,也给自己做个记号. 图片识别的用途:很多人用它去破解网站的验证码,用于达到自动刷票或者是批量 ...

  4. LoRa术语

    ADR      Adaptive Data Rate          自适应数据率 AES      Advanced Encryption Standard        高级加密标准 AFA  ...

  5. Java基础——工厂模式

    通过学习,一句话概括Java工厂模式的特点——通过建立一个工厂来创建对象,不必关心构造对象实例能不能被实例化啊等诸多细节和复杂过程. 工厂模式呢?就像我们从劳动密集型社会转型到技术密集型社会.打个比方 ...

  6. Android - Dagger2 使用和原理

    Dagger2从入门到放弃再到恍然大悟 http://www.jianshu.com/p/cd2c1c9f68d4 http://www.jianshu.com/p/39d1df6c877d http ...

  7. 面向对象设计模式_享元模式(Flyweight Pattern)解读

    场景:程序需要不断创建大量相似的细粒度对象,会造成严重的内存负载.我们可以选择享元模式解决该问题. 享元抽象:Flyweight 描述享元的抽象结构.它包含内蕴和外蕴部分(别被术语迷惑,这是一种比较深 ...

  8. js中Date 方法

    Date (对象) Date 对象能够使你获得相对于国际标准时间(格林威治标准时间,现在被称为 UTC-Universal Coordinated Time)或者是 Flash 播放器正运行的操作系统 ...

  9. Linux常用基本命令(file,chown)

    1,file命令作用,查看文件的类型 ghostwu@dev:~$ .htm ./linux/rename ghostwu@dev:~$ .htm ./linux/rename/.htm: empty ...

  10. 【学习笔记】---老男孩学Python,day1

    老早同学就推荐自己学编程了,因为各种事耽误了几年的时间,也可以说自己没有居安思危的意识吧… 直到今年2月份决定掏钱学线上课,但是又被兼职打断了,公司忙,兼职事多,拖来拖去只能把课程延期.这一拖就到了五 ...