2021-08-18 B. Box Fitting

这篇博客介绍了如何使用优先队列解决一个计算机科学中的几何问题。给定一组高度为1且宽度为2的幂的矩形,以及一个具有特定宽度的二维盒子,任务是找到最小的盒子高度以容纳所有矩形。博主通过创建一个从大到小的优先队列,模拟将矩形放入盒子的过程,展示了解决此问题的AC代码。博客重点讨论了优先队列的数据结构及其在算法中的应用。
摘要由CSDN通过智能技术生成

You are given n rectangles, each of height 1. Each rectangle’s width is a power of 2 (i. e. it can be represented as 2x for some non-negative integer x).

You are also given a two-dimensional box of width W. Note that W may or may not be a power of 2. Moreover, W is at least as large as the width of the largest rectangle.

You have to find the smallest height of this box, such that it is able to fit all the given rectangles. It is allowed to have some empty space left in this box after fitting all the rectangles.

You cannot rotate the given rectangles to make them fit into the box. Moreover, any two distinct rectangles must not overlap, i. e., any two distinct rectangles must have zero intersection area.

See notes for visual explanation of sample input.

Input
The first line of input contains one integer t (1≤t≤5⋅103) — the number of test cases. Each test case consists of two lines.

For each test case:

the first line contains two integers n (1≤n≤105) and W (1≤W≤109);
the second line contains n integers w1,w2,…,wn (1≤wi≤106), where wi is the width of the i-th rectangle. Each wi is a power of 2;
additionally, maxi=1nwi≤W.
The sum of n over all test cases does not exceed 105.

Output
Output t integers. The i-th integer should be equal to the answer to the i-th test case — the smallest height of the box.

由于本人很水,先补充一点队列的知识:
本题使用优先队列
优先队列继承了队列所有的特性并自带排序功能
声明一个队列如下:

priority_queue<Type, Container, Functional> //默认从大到小

其中Type是数据类型,Container是容器类型(必须是用数组实现的容器,不能是list,可以是vector),Functional是排序方法

priority_queue <int, vector<int>, greater<int>> // 升序队列
priority_queue <int, vector<int>, greater<int>> // 降序队列

优先队列的基本操作和队列差不多,主要有:

top // 访问头部元素
empty // 队列是否为空
size // 返回队列里容器个数
push // 插入元素到队尾并排序
pop // 弹出头部元素
swap // 交换内容

进入正题
题目大意:给一堆高度为1,宽度为2的幂的方块,需要一个至少多高的盒子(宽度已知)可以把这些方块都放进去
题解:不需要考虑方块的高度(因为都是1),所以只需要考虑方块的宽度。首先,把盒子从大到小放进去(ps:为什么从大到小:因为大的不好放,小的很好塞进去,所以先从大的放起),开辟一个从大到小的优先队列,先放一个空盒子进去,如果 a[i] 大于队首(即没有能放进 a[i] 的层),那就开辟一个新的层,存放w - a[i] 的值,如果队首大于等于 a[i] 就用队首减 a[i]
AC代码:

#include<bits/stdc++.h>
#define ll long long
#define maxn 1000005
#define rep(i, a, b) for(int i = a; i <= b; i ++) // 升序 
#define per(i, a, b) for(int i = a; i >= b; i ++) // 降序 
int a[maxn];
using namespace std;
int main()
{
	int t;
	cin >> t;
	while(t--){
		int n, w;
		cin >> n >> w;
		rep(i, 1, n){
			cin >> a[i];
		}
		sort(a + 1, a + 1 + n, greater<int>());
		priority_queue <int, vector<int>, less<int>> q;
		q.push(w);
		rep(i, 1, n){
			if(q.top() >= a[i]){
				int V = q.top();
				q.pop();
				q.push(V - a[i]);
			} else {
				q.push(w - a[i]);
			}
		}
		cout << q.size() << endl;
	} 
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值