Codeforces Global Round 14 C. Phoenix and Towers(贪心/优先队列)
Phoenix has n blocks of height h1,h2,…,hn, and all hi don't exceed some value x. He plans to stack all 𝑛n blocks into m separate towers. The height of a tower is simply the sum of the heights of its blocks. For the towers to look beautiful, no two towers may have a height difference of strictly more than x.
Please help Phoenix build m towers that look beautiful. Each tower must have at least one block and all blocks must be used.
Input
The input consists of multiple test cases. The first line contains an integer t (1≤t≤1000) — the number of test cases.
The first line of each test case contains three integers n, m, and x (1≤m≤n≤10^5; 1≤x≤10^4) — the number of blocks, the number of towers to build, and the maximum acceptable height difference of any two towers, respectively.
The second line of each test case contains n space-separated integers (1≤hi≤x) — the heights of the blocks.
It is guaranteed that the sum of n over all the test cases will not exceed 10^5.
Output
For each test case, if Phoenix cannot build m towers that look beautiful, print NO. Otherwise, print YES, followed by n integers y1,y2,…,yn, where yi (1≤yi≤m) is the index of the tower that the i-th block is placed in.
If there are multiple solutions, print any of them.
Example
input
Copy
2
5 2 3
1 2 3 1 2
4 3 3
1 1 2 3
output
Copy
YES
1 1 1 2 2
YES
1 2 2 3
堆贪心,每次从当前堆中取出高度最小的塔,将当前块加上去即可。证明如下:当有两个塔高度相差超过x时,因为每个块的高度小于x,因此相差的必定为两个块以上,而由贪心策略每次都是往最矮的塔上面放,不可能出现相差两个块的情况(模拟一下易知)。
#include <bits/stdc++.h>
using namespace std;
int n, m, x;
int b[100005], tower[100005], ans[100005];
struct node {
int id, h;
bool operator < (const node &o) const {
return h > o.h;
}
};
int main() {
int t;
cin >> t;
while(t--) {
cin >> n >> m >> x;
priority_queue<node> q;
for(int i = 1; i <= n; i++) {
cin >> b[i];
}
for(int i = 1; i <= m; i++) tower[i] = 0;
//要求所有塔的最大值和最小值相差不超过x
for(int i = 1; i <= m; i++) {
node now = {i, 0};
q.push(now);
}
for(int i = 1; i <= n; i++) {
node now = q.top();
q.pop();
ans[i] = now.id;//注意这里的b数组是已经排序过的
now.h += b[i];
q.push(now);
}
int minn = 0x3f3f3f3f, maxx = 0;
while(q.size()) {
node now = q.top(); q.pop();
minn = min(minn, now.h);
maxx = max(maxx, now.h);
}
if(maxx - minn > x || !minn || !maxx) {
cout << "NO" << endl;
continue;
}
cout << "YES" << endl;
for(int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
cout << endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2020-05-03 POJ1236 Network of Schools(强连通分量)
2020-05-03 P3387 【模板】缩点(Tarjan求强连通分量)