https://www.luogu.org/problemnew/show/P1034

可能是数据太水了瞎搞都可以过。

判断两个平行于坐标轴的矩形相交(含顶点与边相交)的代码一并附上。

记得这里的xy和udlr是指数学上的坐标轴。

#include<bits/stdc++.h>
using namespace std;
#define ll long long struct Point{
int x,y;
Point(int x=,int y=){
this->x=x,this->y=y;
}
}p[]; struct Rectangle{
int u,d,l,r;
Rectangle(){
u=d=l=r=-;
}
bool inside(Point p){
if(p.x>=l&&p.x<=r&&p.y>=d&&p.y<=u)
return true;
return false;
}
bool intersect_help(Rectangle r2){
Point r1p1(l,u);
if(r2.inside(r1p1))
return ;
Point r1p2(r,u);
if(r2.inside(r1p2))
return ;
Point r1p3(r,d);
if(r2.inside(r1p3))
return ;
Point r1p4(l,d);
if(r2.inside(r1p4))
return ;
return ;
} bool intersect(Rectangle r2){
if(u==-||r2.u==-)
return ;
if(intersect_help(r2))
return ;
if(r2.intersect_help(*this))
return ;
if(l<=r2.l&&r>=r2.r&&u<=r2.u&&d>=r2.d)
return ;
if(r2.l<=l&&r2.r>=r&&r2.u<=u&&r2.d>=d)
return ;
return ;
} int area(){
return (r-l)*(u-d);
} void extend(Point p){
if(u==-){
l=r=p.x;
u=d=p.y;
return;
}
else{
l=min(l,p.x);
r=max(r,p.x);
u=max(u,p.y);
d=min(d,p.y);
return;
}
} void show(){
printf(" u=%d d=%d l=%d r=%d\n",u,d,l,r);
}
}; int n,k;
int ans=0x3f3f3f3f;
void dfs4(int id,Rectangle r1,Rectangle r2,Rectangle r3,Rectangle r4){
//r1.show(),r2.show(),r3.show(),r4.show();
//printf("---------\n"); if(id>n){
ans=min(ans,r1.area()+r2.area()+r3.area()+r4.area());
return;
} Point pi=p[id];
if(r1.inside(pi)||r2.inside(pi)||r3.inside(pi)||r4.inside(pi))
dfs4(id+,r1,r2,r3,r4);
else{
Rectangle rr1=r1;
rr1.extend(pi);
if(rr1.intersect(r2)||rr1.intersect(r3)||rr1.intersect(r4))
;
else{
dfs4(id+,rr1,r2,r3,r4);
} Rectangle rr2=r2;
rr2.extend(pi);
if(rr2.intersect(r1)||rr2.intersect(r3)||rr2.intersect(r4))
;
else{
dfs4(id+,r1,rr2,r3,r4);
} Rectangle rr3=r3;
rr3.extend(pi);
if(rr3.intersect(r1)||rr3.intersect(r2)||rr3.intersect(r4))
;
else{
dfs4(id+,r1,r2,rr3,r4);
} Rectangle rr4=r4;
rr4.extend(pi);
if(rr4.intersect(r1)||rr4.intersect(r2)||rr4.intersect(r3))
;
else{
dfs4(id+,r1,r2,r3,rr4);
}
}
} void dfs3(int id,Rectangle r1,Rectangle r2,Rectangle r3){
//r1.show(),r2.show(),r3.show();
//printf("---------\n"); if(id>n){
ans=min(ans,r1.area()+r2.area()+r3.area());
return;
} Point pi=p[id];
if(r1.inside(pi)||r2.inside(pi)||r3.inside(pi))
dfs3(id+,r1,r2,r3);
else{
Rectangle rr1=r1;
rr1.extend(pi);
if(rr1.intersect(r2)||rr1.intersect(r3))
;
else{
dfs3(id+,rr1,r2,r3);
} Rectangle rr2=r2;
rr2.extend(pi);
if(rr2.intersect(r1)||rr2.intersect(r3))
;
else{
dfs3(id+,r1,rr2,r3);
} Rectangle rr3=r3;
rr3.extend(pi);
if(rr3.intersect(r1)||rr3.intersect(r2))
;
else{
dfs3(id+,r1,r2,rr3);
}
}
} void dfs2(int id,Rectangle r1,Rectangle r2){
if(id>n){
//r1.show(),r2.show();
int tans=r1.area()+r2.area();
ans=min(ans,tans);
//printf("tans=%d\n---------\n",tans);
return;
} Point pi=p[id];
if(r1.inside(pi)||r2.inside(pi))
dfs2(id+,r1,r2);
else{
Rectangle rr1=r1;
rr1.extend(pi);
if(rr1.intersect(r2))
;
else{
dfs2(id+,rr1,r2);
} Rectangle rr2=r2;
rr2.extend(pi);
if(rr2.intersect(r1))
;
else{
dfs2(id+,r1,rr2);
}
}
} void dfs(int id,Rectangle r1){
//r1.show();
//printf("---------\n"); if(id>n){
ans=min(ans,r1.area());
return;
} Point pi=p[id];
if(r1.inside(pi))
dfs(id+,r1);
else{
Rectangle rr1=r1;
rr1.extend(pi);
dfs(id+,rr1);
}
} int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
}
Rectangle r;
switch(k){
case :
dfs(,r);
break;
case :
dfs2(,r,r);
break;
case :
dfs3(,r,r,r);
break;
case :
dfs4(,r,r,r,r);
}
printf("%d\n",ans);
}

加入最优性剪枝:22ms,快了3倍?

#include<bits/stdc++.h>
using namespace std;
#define ll long long struct Point{
int x,y;
Point(int x=,int y=){
this->x=x,this->y=y;
}
}p[]; struct Rectangle{
int u,d,l,r;
Rectangle(){
u=d=l=r=-;
}
bool inside(Point p){
if(p.x>=l&&p.x<=r&&p.y>=d&&p.y<=u)
return true;
return false;
}
bool intersect_help(Rectangle r2){
Point r1p1(l,u);
if(r2.inside(r1p1))
return ;
Point r1p2(r,u);
if(r2.inside(r1p2))
return ;
Point r1p3(r,d);
if(r2.inside(r1p3))
return ;
Point r1p4(l,d);
if(r2.inside(r1p4))
return ;
return ;
} bool intersect(Rectangle r2){
if(u==-||r2.u==-)
return ;
if(intersect_help(r2))
return ;
if(r2.intersect_help(*this))
return ;
if(l<=r2.l&&r>=r2.r&&u<=r2.u&&d>=r2.d)
return ;
if(r2.l<=l&&r2.r>=r&&r2.u<=u&&r2.d>=d)
return ;
return ;
} int area(){
return (r-l)*(u-d);
} void extend(Point p){
if(u==-){
l=r=p.x;
u=d=p.y;
return;
}
else{
l=min(l,p.x);
r=max(r,p.x);
u=max(u,p.y);
d=min(d,p.y);
return;
}
} void show(){
printf(" u=%d d=%d l=%d r=%d\n",u,d,l,r);
}
}; int n,k;
int ans=0x3f3f3f3f;
void dfs4(int id,Rectangle r1,Rectangle r2,Rectangle r3,Rectangle r4){
//r1.show(),r2.show(),r3.show(),r4.show();
//printf("---------\n");
int tans=r1.area()+r2.area()+r3.area()+r4.area();
if(tans>=ans)
return;
if(id>n){
ans=min(ans,tans);
return;
} Point pi=p[id];
if(r1.inside(pi)||r2.inside(pi)||r3.inside(pi)||r4.inside(pi))
dfs4(id+,r1,r2,r3,r4);
else{
Rectangle rr1=r1;
rr1.extend(pi);
if(rr1.intersect(r2)||rr1.intersect(r3)||rr1.intersect(r4))
;
else{
dfs4(id+,rr1,r2,r3,r4);
} Rectangle rr2=r2;
rr2.extend(pi);
if(rr2.intersect(r1)||rr2.intersect(r3)||rr2.intersect(r4))
;
else{
dfs4(id+,r1,rr2,r3,r4);
} Rectangle rr3=r3;
rr3.extend(pi);
if(rr3.intersect(r1)||rr3.intersect(r2)||rr3.intersect(r4))
;
else{
dfs4(id+,r1,r2,rr3,r4);
} Rectangle rr4=r4;
rr4.extend(pi);
if(rr4.intersect(r1)||rr4.intersect(r2)||rr4.intersect(r3))
;
else{
dfs4(id+,r1,r2,r3,rr4);
}
}
} void dfs3(int id,Rectangle r1,Rectangle r2,Rectangle r3){
//r1.show(),r2.show(),r3.show();
//printf("---------\n");
int tans=r1.area()+r2.area()+r3.area();
if(tans>=ans)
return; if(id>n){
ans=min(ans,tans);
return;
} Point pi=p[id];
if(r1.inside(pi)||r2.inside(pi)||r3.inside(pi))
dfs3(id+,r1,r2,r3);
else{
Rectangle rr1=r1;
rr1.extend(pi);
if(rr1.intersect(r2)||rr1.intersect(r3))
;
else{
dfs3(id+,rr1,r2,r3);
} Rectangle rr2=r2;
rr2.extend(pi);
if(rr2.intersect(r1)||rr2.intersect(r3))
;
else{
dfs3(id+,r1,rr2,r3);
} Rectangle rr3=r3;
rr3.extend(pi);
if(rr3.intersect(r1)||rr3.intersect(r2))
;
else{
dfs3(id+,r1,r2,rr3);
}
}
} void dfs2(int id,Rectangle r1,Rectangle r2){
int tans=r1.area()+r2.area();
if(tans>=ans)
return; if(id>n){
//r1.show(),r2.show();
ans=min(ans,tans);
//printf("tans=%d\n---------\n",tans);
return;
} Point pi=p[id];
if(r1.inside(pi)||r2.inside(pi))
dfs2(id+,r1,r2);
else{
Rectangle rr1=r1;
rr1.extend(pi);
if(rr1.intersect(r2))
;
else{
dfs2(id+,rr1,r2);
} Rectangle rr2=r2;
rr2.extend(pi);
if(rr2.intersect(r1))
;
else{
dfs2(id+,r1,rr2);
}
}
} void dfs(int id,Rectangle r1){
//r1.show();
//printf("---------\n");
int tans=r1.area();
if(tans>=ans)
return; if(id>n){
ans=min(ans,r1.area());
return;
} Point pi=p[id];
if(r1.inside(pi))
dfs(id+,r1);
else{
Rectangle rr1=r1;
rr1.extend(pi);
dfs(id+,rr1);
}
} int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%d%d",&p[i].x,&p[i].y);
}
Rectangle r;
switch(k){
case :
dfs(,r);
break;
case :
dfs2(,r,r);
break;
case :
dfs3(,r,r,r);
break;
case :
dfs4(,r,r,r,r);
}
printf("%d\n",ans);
}

洛谷 - P1034 - 矩形覆盖 - dfs的更多相关文章

  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. [NOIP2002] 提高组 洛谷P1034 矩形覆盖

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

  4. 洛谷——P1034 矩形覆盖

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

  5. 【NOIP2002】矩形覆盖 DFS

    首先,我喜欢愤怒搜索,因为尽管说K<=4,的确K小于或等于3的. 当然某些K<=3还600ms的我就不加评论了. 好吧,可是怎么搜呢?我们考虑到矩形数量非常少,所以能够怒搜矩形. 一些神做 ...

  6. 洛谷 P2218 [HAOI2007]覆盖问题 解题报告

    P2218 [HAOI2007]覆盖问题 题目描述 某人在山上种了\(N\)棵小树苗.冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他 ...

  7. P1034 矩形覆盖

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

  8. 洛谷 P1191 矩形 题解

    P1191 矩形 题目描述 给出一个 \(n \times n\)的矩阵,矩阵中,有些格子被染成白色,有些格子被染成黑色,现要求矩阵中白色矩形的数量 输入格式 第一行,一个整数\(n\),表示矩形的大 ...

  9. 洛谷P1120小木棍[DFS]

    题目描述 乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50. 现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度. 给出每段小木棍的长度,编 ...

随机推荐

  1. BUPT复试专题—字符串处理(2016)

    题目描述 有以下三种操作. (1)COPY l r(0<=l<=r<n),n代表s串的长度.这个表示将s串从l到r的序列复制到剪贴板t里面,覆盖t字符串. 例如s为abcde     ...

  2. BUPT复试专题—三元组(2016)

    题目描述 给你一个长度为m的数组(数组元素从0到m-1),如果数组里有a[i]+a[j]==a[k](i,j,k大于等于0并且小于m),便称之为三元组.现在给你一个数组,让你求三元组的个数. 例如m为 ...

  3. springboot mybatis 项目框架源码 shiro 集成代码生成器 ehcache缓存

    1.代码生成器: [正反双向](单表.主表.明细表.树形表,快速开发利器)freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本.处理类.service等完整模块2. ...

  4. Atlassian Confluence安装

    前言 Confluence与Jira 由于线上jira和confluence之前互相关联,confluence的登录用户全部关联自jira的用户,confluence安装时会提示是否关联jira,由于 ...

  5. sqlite学习笔记10:C语言中使用sqlite之查询和更新数据

    前面说到的 sqlite_exec() 中的第三个參数, SQLite 将为 sql 參数内运行的每一个 SELECT 语句中处理的每一个记录调用这个回调函数. 本节加入了两个函数.selectFro ...

  6. subclassdlgitem

    subclassdlgitem 该函数用来子类化一个控件. Subclass(子类化)是MFC中最常用的窗体技术之一.子类化完成两个工作:一是把窗体类对象attach到一个windows窗体实体中(即 ...

  7. Java,多个线程对同一个数据源的访问

    当多个线程对同一个数据源进行访问时,应对线程同步或加锁.为何?举个简单的例子:有一个共享的数据源dataSource,其值为0.有两个线程,Thread1和Thread2.Thread1的任务是将da ...

  8. 20170218 OO-ALV标准工具栏按钮

    原文地址:OO ALV 工具栏对于的功能码   图标与对应的 功能码 明细 &DETAIL 检查 &CHECK 刷新 &REFRESH 剪切 &LOCAL&CU ...

  9. hihoCoder 1584 Bounce 【数学规律】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)

    #1584 : Bounce 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 For Argo, it is very interesting watching a cir ...

  10. file类简单操作

    file类可表示文件或文件夹 import java.io.File; import java.io.FilenameFilter; import java.io.IOException; impor ...