L2-046 天梯赛的赛场安排 - java

题目解析

给定n所学校,以及每间考场的容量。

问每个学校需要几个考场,以及总考场数

解题思路

模拟

可以使用优先队列来实现

每次将最少的剩余排队人数 拿来去判断 三种情况

  • 如果人数大于等于每间考场容量:新开一间考场,当前考场剩余容量为0。再将剩余的人数再次去排队
  • 如果当前人数小于容量且能在已有的考场中找到能容纳的考场,则将这些人放入该考场
  • 否则,新开一间考场,剩余人数 = 每间考场容量 - 人数

注: 不知道为啥java的最后一个数据就是答案错误

代码

import java.io.*;
import java.util.*;

public class Main
{
	static int N = (int) 1e4 + 10;
	static int M = (int) 1e4;

	static String school[] = new String[N + 10]; // 学校名称
	static int cnt[] = new int[N + 10]; // 每个学校需要的考场
	static int pos[] = new int[N * 500 + 10]; // 每个考场剩余的人数

	static PriorityQueue<Integer> pr = new PriorityQueue<Integer>(); // 剩余排队的人数,以及编号 (人数 * 10000 + 编号)

	public static void main(String[] args)
	{
		int n = sc.nextInt();
		int c = sc.nextInt();

		for (int i = 1; i <= n; i++)
		{
			school[i] = sc.next();
			int num = sc.nextInt();
			pr.offer(num * M + i);
		}

		int res = 0; // 考场数量
		while (pr.size() > 0)
		{
			int u = pr.poll();
			int k = u / M; // 学校剩余人数
			int id = u % M; // 学校编号

			cnt[id]++; // 当前学校考场增加一个

//			是否有满足条件1的考场
			if (k >= c)
			{
				pos[++res] = 0; // 新增考场,剩余人数为0
				k -= c; // 学校剩余人数
				if (k != 0)
					pr.add(k * M + id); // 当前学校处理下一轮
				continue;
			}

//			是否有满足条件2的考场
			boolean f = false;
			for (int i = 1; i <= res; i++)
			{
				if (pos[i] >= k)
				{
					f = true;
					pos[i] -= k; // 更新当前考场剩余的人数
					break;
				}
			}
			
//			是否有满足条件3的考场
			if (!f)
				pos[++res] = c - k; // 新开一个考场
		}

		for (int i = 1; i <= n; i++)
			out.println(school[i] + " " + cnt[i]);
		out.println(res);

		out.flush();
		out.close();
	}

	static Scanner sc = new Scanner(System.in);
	static PrintWriter out = new PrintWriter(System.out);

}

c++

#include <iostream>
#include <queue>

using namespace std;

const int N = 1e4 + 10, M = 1e4;
string school[N]; // 学校名称
int cnt[N]; // 每个学校需要的考场
int pos[N * 500]; // 每个考场剩余的人数

priority_queue<int> q; // 剩余排队的人数,以及编号 (人数 * 10000 + 编号)

int main()
{
    int n, c; cin >> n >> c;
    for(int i = 1; i <= n; i ++)
    {
        int x; cin >> school[i] >> x;
        q.push(x * M + i);
    }
    
    int res = 0; // 考场数量
    while(q.size() > 0)
    {
        int u = q.top(); q.pop();
        int k = u / M; // 学校剩余人数
        int id = u % M; // 学校编号
        
        cnt[id] ++; // 当前学校考场增加一个
        
        // 是否有满足条件1的考场
        if(k >= c)
        {
            pos[++res] = 0; // 新增考场,剩余人数为0
            k -= c; // 学校剩余人数
            if(k > 0) q.push(k * M + id); // 当前学校处理下一轮
            continue;
        }
        
        // 是否有满足条件2的考场
        bool f = false;
        for(int i = 1; i <= res; i ++)
        {
            if(pos[i] >= k)
            {
                f = true;
                pos[i] -= k; // 更新当前考场剩余的人数
                break;
            }
        }
        
        // 是否有满足条件3的考场
        if(!f) pos[++res] = c - k; // 新开一个考场
    }
    
    for(int i = 1; i <= n; i ++)
        cout << school[i] << " " << cnt[i] << endl;
    cout << res;
    
    return 0;
}

PriorityQueue


团体程序设计天梯赛-练习集-java

赞赏