原题链接:蓝桥杯2024年第十五届决赛真题-套手镯
问题思路:
手镯可以用矩形的上下左右边界来描述,每个手镯都有一个左、右、下、上的边界。
目标是找出一个矩形区域,计算这个矩形内最多能容纳多少个手镯。矩形可以按两种方向摆放,宽×高或高×宽,因此需要考虑两种情形。
解决策略:
滑动窗口+优先队列:我们使用一个优先队列来存储当前在矩形范围内的手镯。通过滑动矩形的上下边界,并动态维护符合条件的手镯集合,计算出矩形内最多手镯数量。
排序:先根据手镯的右边界进行排序,这样可以方便地通过滑动窗口的方式检查哪些手镯能放进矩形。
核心算法:
通过外层循环,固定矩形的下边界(每次尝试一个不同的下边界),然后计算矩形的上边界。
内层循环遍历所有手镯,判断哪些手镯的上下边界在当前的矩形范围内。
使用优先队列存储当前上下边界内的手镯,左边界小于矩形右边界减去矩形宽度的手镯被移除。
最终计算在矩形内能容纳最多的手镯数量。
参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10; // 定义数组大小的上限
const int MOD = 1e9 + 7; // 常用的大质数MOD
ll n, w, h; // n是手镯数量,w和h是矩形的宽度和高度
// 定义结构体Node表示一个手镯的四个边界
struct Node {
int l, r, b, t; // 左、右、下、上边界
// 重载小于运算符,按照左边界从大到小排序,优先队列中会保持左边界从小到大排列
bool operator< (const Node &u) const {
return l > u.l;
}
} a[N];
// solve函数:计算矩形区域内可以容纳最多的手镯数
int solve(int tw, int th) {
int res = 0; // 记录结果(最大手镯数)
// 外层循环:固定矩形的下边界line
for (int i = 0; i < n; i++) {
int bottom = a[i].b; // 当前手镯的下边界
int top = bottom + th; // 计算矩形的上边界
priority_queue<Node> q; // 优先队列,用来存储在当前上下边界之内的手镯
// 内层循环:检查所有手镯是否在当前的上下边界范围内
for (int j = 0; j < n; j++) {
// 如果手镯的上下边界在当前矩形范围内
if (a[j].b >= bottom && a[j].t <= top) {
q.push(a[j]); // 将符合条件的手镯加入优先队列
}
// 移除不再符合当前左右边界范围的手镯
while (!q.empty() && q.top().l < a[j].r - tw) {
q.pop(); // 移除左边界小于当前手镯右边界-矩形宽度的手镯
}
// 更新最大值,计算当前矩形内的手镯数量
res = max(res, (int)q.size());
}
}
return res; // 返回最大手镯数
}
// cmp函数:按照手镯右边界从小到大排序
bool cmp(Node a, Node b) {
return a.r < b.r;
}
int main() {
cin >> n >> w >> h; // 输入手镯数量n和矩形的宽度w和高度h
// 输入每个手镯的坐标和半径,并计算出每个手镯的四个边界
for (int i = 0; i < n; i++) {
int x, y, r;
cin >> x >> y >> r; // 输入手镯的中心坐标(x, y)和半径r
a[i].l = x - r; // 计算左边界
a[i].r = x + r; // 计算右边界
a[i].b = y - r; // 计算下边界
a[i].t = y + r; // 计算上边界
}
sort(a, a + n, cmp); // 根据右边界升序排序所有手镯
// 分别尝试两种矩形方向,w x h 和 h x w
int res1 = solve(w, h);
int res2 = solve(h, w);
// 输出两种方向中的最大手镯数
cout << max(res1, res2) << endl;
return 0;
}0.0分
0 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复