P1034 [NOIP2002 提高组] 矩形覆盖

news2024/11/26 10:23:10

题目描述

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

这些点可以用 �k 个矩形全部覆盖,矩形的边平行于坐标轴。当 �=2k=2 时,可用如图二的两个矩形 �1,�2s1​,s2​ 覆盖,�1,�2s1​,s2​ 面积和为 44。问题是当 �n 个点坐标和 �k 给出后,怎样才能使得覆盖所有点的 �k 个矩形的面积之和为最小呢?
约定:覆盖一个点的矩形面积为 00;覆盖平行于坐标轴直线上点的矩形面积也为 00。各个矩形必须完全分开(边线与顶点也都不能重合)。

输入格式

第一行共两个整数 �,�n,k,含义如题面所示。

接下来 �n 行,其中第 �+1i+1 行有两个整数 ��,��xi​,yi​,表示平面上第 �i 个点的坐标。

输出格式

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

输入输出样例

输入 #1复制

4 2
1 1
2 2
3 6
0 7

输出 #1复制

4

说明/提示

对于 100%100% 数据,满足 1≤�≤501≤n≤50,1≤�≤41≤k≤4,0≤��,��≤5000≤xi​,yi​≤500。

【题目来源】

NOIP 2002 提高组第四题

数据这么小,不写暴搜对不起这么良心的数据啊

本题解介绍如何思路清晰地快速写出暴力。

题目分析:

拿到题面读懂题意后,如此之小的数据范围就告诉我们,这道题不是状压就是暴搜,你说状压吧又没看出来有什么好转移的东西,那就是暴搜跑不脱了。

那么现在有两个方向来搜,一个是枚举每个矩形包含了哪些点,一个是枚举每个点属于哪个矩形。因为我们暴搜的结构需要资瓷回溯,无疑每次只加一个点的后一种结构对于回溯的操作更为友善。

那么dfs的结构呼之欲出:

void dfs(当前考虑的点, 当前总面积) {
	if(当前面积 >= 已有最优解) return;
	if(搜索深度 == n) {
		if(矩形互不相交(满足题面要求))
			更新最优解;
		return; 
	}
	for(枚举每个矩形) {
		tmp = 当前选定矩形;
		当前点加入选定矩形;
		dfs(下一个点, 新的总面积);
		当前选定矩形 = tmp; #回溯!#
	} 
}

有人可能会问了,为什么要最后才来检查解的合法性呢?

其实对于这么小的数据,效率都差不多:

最后再检查 # 32ms ---/\ VS \/--- 随时检查 # 31ms

考虑到对于矩形这个对象需要资瓷的操作比较多,我们将其封装于一个������struct里:

struct mat {
	int lx, ly, rx, ry;//左上角坐标,右下角坐标
	bool cnt;//是否使用过(覆盖着 点)
	void add(int x, int y) {//添加点
		if(!cnt) {//还没用过
			lx = rx = x;
			ly = ry = y;
			cnt = 1;
		} else {//更新覆盖范围
			if(x < lx) lx = x;
			else if(x > rx) rx = x;
			if(y > ly) ly = y;
			else if(y < ry) ry = y;
		}
	}
	bool inmat(int x, int y) const {//判断点是否在矩形里
		return lx <= x && x <= rx && ry <= y && y <= ly;
	}
	int operator() () {//求面积
		if(!cnt) return 0;
		return (rx - lx) * (ly - ry);
	}
	bool operator* (const mat &o) {//判断两个矩形是否相交
		if(!cnt || !o.cnt) return 0;
		return o.inmat(lx, ly) || o.inmat(lx, ry) ||
			o.inmat(rx, ly) || o.inmat(rx, ry);
	}
} km[5];//矩形

有了这么强大的基本操作资瓷,check函数还难写?

bool check() {
	for(int i = 1;i <= k;i++)
		for(int j = i + 1;j <= k;j++)
			if(km[i] * km[j]) return 0;
	return 1;
}

综上所述,您还觉得暴力无从下手?

代码实现:

#include <bits/stdc++.h>
#define N 55
using namespace std;

int n, k, x[N], y[N], ans = INT_MAX >> 2;
struct mat {
	int lx, ly, rx, ry;
	bool cnt;
	void add(int x, int y) {
		if(!cnt) {
			lx = rx = x;
			ly = ry = y;
			cnt = 1;
		} else {
			if(x < lx) lx = x;
			else if(x > rx) rx = x;
			if(y > ly) ly = y;
			else if(y < ry) ry = y;
		}
	}
	bool inmat(int x, int y) const {
		return lx <= x && x <= rx && ry <= y && y <= ly;
	}
	int operator() () {
		if(!cnt) return 0;
		return (rx - lx) * (ly - ry);
	}
	bool operator* (const mat &o) {
		if(!cnt || !o.cnt) return 0;
		return o.inmat(lx, ly) || o.inmat(lx, ry) ||
			o.inmat(rx, ly) || o.inmat(rx, ry);
	}
} km[5];

bool check() {
	for(int i = 1;i <= k;i++)
		for(int j = i + 1;j <= k;j++)
			if(km[i] * km[j]) return 0;
	return 1;
}

void dfs(int i, int area) {
	if(area >= ans) return;
	if(i == n) {
		if(check())
			if(ans > area) ans = area;
		return;
	}
	mat tmp;
	for(int j = 1;j <= k;j++) {
		tmp = km[j];
		km[j].add(x[i], y[i]);
		dfs(i + 1, area - tmp() + km[j]());
		km[j] = tmp;//关键的回溯
	}
}

int main() {
	scanf("%d%d", &n, &k);
	for(int i = 0;i < n;i++)
		scanf("%d%d", x + i, y + i);
	dfs(0, 0);
	printf("%d", ans);
	return 0;
}

后记:

练暴搜的好题,唯一的难点在于回溯,理清楚搜索逻辑 其实并不复杂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/460796.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设备树总结

设备树的概念: 设备树&#xff08;Device Tree:DT&#xff09;是用来描述设备信息的一种树形结构。设备树文件在linux内核启动的时候传递到内核被内核解析。设备树中每一个设备节点中的信息构成了一个属性链表&#xff0c;如果驱动想要使用这个设备信息&#xff0c;只需要在这…

UE4架构初识(五)

UE4仿真引擎学习 一、架构基础 1. GameInstance UE提供的方案是一以贯之的&#xff0c;为我们提供了一个GameInstance类。为了受益于UObject的反射创建能力&#xff0c;直接继承于UObject&#xff0c;这样就可以依据一个Class直接动态创建出来具体的GameInstance子类。 UGam…

Pytest接口自动化测试实战演练

结合单元测试框架pytest数据驱动模型allure 目录 api&#xff1a; 存储测试接口conftest.py :设置前置操作目前前置操作&#xff1a;1、获取token并传入headers&#xff0c;2、获取命令行参数给到环境变量,指定运行环境commmon&#xff1a;存储封装的公共方法connect_mysql.p…

C. Magic Ship(二分 + 前缀和)

Problem - C - Codeforces 你是一艘船的船长。最初你站在一个点(x1&#xff0c;y1)上&#xff08;很明显&#xff0c;海上的所有位置都可以用笛卡尔平面描述&#xff09;&#xff0c;你想要前往一个点(x2&#xff0c;y2)。 你知道天气预报——长度为n的字符串s&#xff0c;仅由…

实战详解Docker快速搭建部署ELK

一.安装前须知 以下步骤在 VMware 中的 centos 7 中操作&#xff0c;ip 地址为&#xff1a;192.168.161.128&#xff1b; 注意安装的时候最好统一版本&#xff0c;否则后面会出现许多问题&#xff0c;进官网搜索对应镜像&#xff0c;查看 Tags 标签下的版本&#xff0c;目前我…

记一次死锁问题

最近在做一个需求&#xff0c;碰到了死锁的问题&#xff0c;记录下解决问题的过程 背景 这个需求要改动一个接口&#xff0c;我这边称为A接口&#xff0c;原先的逻辑是A接口内部会调用c方法&#xff0c;c方法是一个dubbo方法&#xff0c; 现在需要再A接口里添加调用B方法&…

springcloud之Feign、ribbon设置超时时间和重试机制的总结

目录标题 超时时间ribbon和Feignribbon和Feign默认超时时间关于ribbon和Feign超时时间配置说明 关于hystrix默认超时时间与配置说明 ribbon的重试机制重试的次数hystrix超时时间举个例子 超时时间 feign/ribbon对应的是请求的时间 hystrix对应的是断路器的时间 一般情况下 都是…

【Linux】2. 常见指令

1. 操作系统的定义 在真正了解Linux操作系统之前&#xff0c;我们需要初步明确什么是操作系统 Linux下的基本指令 指令的作用是什么&#xff0c;其实就是相当于Windows的基本操作&#xff0c;Linux操作系统是以命令行显示的&#xff0c;而Windows则是以图形化界面的方式展现…

图像融合方向:《Deep Image Blending》论文理解

《Deep Image Blending》论文理解 论文&#xff1a;《Deep Image Blending》WACV 2020 链接&#xff1a;Deep Image Blending 本文目录 《Deep Image Blending》论文理解论文创新点具体实现思路文中使用的基准方法文章内容解析使用模型整体架构两阶段算法详情第1阶段第2阶段 损…

一款高效、可靠的自动化测试平台,提升效率、降低测试成本

一、开源项目简介 扬帆测试平台是一款高效、可靠的自动化测试平台&#xff0c;旨在帮助团队提升测试效率、降低测试成本。该平台包括用例管理、定时任务、执行记录等功能模块&#xff0c;支持多种类型的测试用例&#xff0c;目前支持API(http和grpc协议)、性能&#xff0c;并且…

轻量级服务器nginx:负载均衡

负载均衡就是让每个设备&#xff0c;以同样的概率&#xff0c;处理用户对于服务器的任务请求&#xff0c;默认采用的负载调度策略就是轮流询问&#xff0c;Nginx作为反向代理服务器安装在服务端&#xff0c;Nginx的功能就是把请求转发给后面的应用服务器. 这里写目录标题 一 负…

差分优化算法——DE

&#x1f34e;道阻且长&#xff0c;行则将至。&#x1f353; 目录 一、DE1.步骤2.特点 二、DE Optimiza1.函数最小值问题2.差分进化算法求解2.Java 实现与结果绘图 一、DE 差分进化算法是一种基于群体智能的优化算法&#xff0c;由Storn和Price于1995年提出&#xff0c;最早用…

vue3+ts开发微信小程序----使用FontAwesome图标的步骤(只适用于面性图标)

vue3ts开发微信小程序----使用FontAwesome图标的步骤&#xff08;只适用于面性图标&#xff09; 因为用的vue3ts 但是对于npm引进FontAwesome来说&#xff0c;好像对于小程序不支持&#xff0c;所以用了引入文件的方式。 下载FontAwesome字体&#xff0c;我用的是5版本的。[官方…

从初识RabbitMQ到安装了解

一、同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你却不…

记 SAM React Demo 转 Vue 遇到的一些问题

前言 SegmentAnything Model (SAM) 是 Meta 开源的分割万物 AI 模型&#xff0c;因笔者主要使用 Vue&#xff0c;因此对官方 Demo 进行了工程迁移工作&#xff0c;这里记录了迁移过程遇到的一些问题。 没有使用多线程加速 官方的 React Demo 项目使用ort-wasm-simd-threaded…

态路小课堂丨浅谈IDC数据中心综合布线互联

在数据中心发展过程中&#xff0c;服务器、光模块等设备更新周期短&#xff0c;迭代快。但是&#xff0c;对于IDC数据中心综合布线系统来说&#xff0c;其使用周期一般都比较长。因此&#xff0c;为了能够匹配IDC数据中心的发展&#xff0c;关于综合布线的设计尤为重要。 目前&…

【vue】elementUI中el-table拖动滚动条的时候固定某一列

文章目录 前言&#xff1a;需求 前言&#xff1a; 写项目的时候有一个需求&#xff0c;就是当el-table的滚动条滑动的时候&#xff0c;可见区域如果没有该列则固定到左侧&#xff0c;由elementUi官方网站可知el-table固定一列的代码如下: fixed为主要的标识 头部固定设置的是t…

leetcode 2336. Smallest Number in Infinite Set(有限集中的最小数字)

实现一个SmallestInfiniteSet类(后面用set简称)&#xff0c;满足以下功能&#xff1a; 初始化时&#xff0c;set含有所有的正整数。 pop函数返回set中最小的整数。 add函数在set中添加一个整数。 思路&#xff1a; set具有以下的功能&#xff1a; 可以取出最小的数字。 可以查…

FPGA入门系列13--异步串口通信

文章简介 本系列文章主要针对FPGA初学者编写&#xff0c;包括FPGA的模块书写、基础语法、状态机、RAM、UART、SPI、VGA、以及功能验证等。将每一个知识点作为一个章节进行讲解&#xff0c;旨在更快速的提升初学者在FPGA开发方面的能力&#xff0c;每一个章节中都有针对性的代码…

Baklib如何帮助企业设计并维护FAQ页面?

作为现代企业的一部分&#xff0c;客户支持服务是为客户提供解决方案、回答问题和解决技术难题的关键部分。而其中最重要的一个基本工具是FAQ页面&#xff08;Frequently Asked Questions&#xff09;&#xff0c;它可以有效地减轻客户支持压力和提高工作效率。然而&#xff0c…