L1-049 天梯赛座位分配(20 分)[java][python][c]

题目 ID :L1-049
题目分数 :20 分
语言:Java / Python

题目描述

天梯赛每年有大量参赛队员,要保证同一所学校的所有队员都不能相邻,分配座位就成为一件比较麻烦的事情。

为此我们制定如下策略:

  1. 假设某赛场有 N 所学校参赛
  2. 第 i 所学校有 M[i] 支队伍,每队 10 位参赛选手
  3. 每校选手排成一列纵队,第 i+1 队的选手排在第 i 队选手之后
  4. 从第 1 所学校开始,各校的第 1 位队员顺次入座,然后是各校的第 2 位队员......以此类推
  5. 如果最后只剩下 1 所学校的队伍还没有分配座位,则需要安排他们的队员隔位就坐

输入格式

  • 第一行:参赛的高校数 N(不超过 100 的正整数)
  • 第二行:N 个不超过 10 的正整数,其中第 i 个数对应第 i 所高校的参赛队伍数,数字间以空格分隔

输出格式

  • 从第 1 所高校的第 1 支队伍开始,顺次输出队员的座位号
  • 每队占一行,座位号间以 1 个空格分隔,行首尾不得有多余空格
  • 每所高校的第一行按 "#X" 输出该校的编号 X,从 1 开始

样例

输入

复制代码
3
3 4 2

输出

复制代码
#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60

解题思路

核心思想是模拟座位分配过程,从 1 号座位开始逐个安排:

  1. 数据结构

    • students[i]:记录第 i 个学校所有队员的座位号列表
    • seatSchool[j]:记录第 j 号座位分配给了哪个学校
  2. 分配逻辑

    • 遍历每个学校,如果该学校还有学生没安排座位
    • 检查当前座位的前一个座位是否已被同校学生占用
    • 若前一个不是本校 → 正常安排到当前座位,座位号 +1
    • 若前一个是本校 → 跳到下下个座位安排,座位号 +2
  3. 终止条件:所有学校的学生都被安排完毕

  4. 输出格式 :每所学校前输出 #X,每 10 个座位号换一行

代码实现

Java

java 复制代码
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] num = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            num[i] = sc.nextInt();
        }

        List<int[]> students = new ArrayList<>(n + 1);
        for (int i = 0; i <= n; i++) {
            students.add(new int[0]);
        }
        int[] seatSchool = new int[100001];
        int cnt = 1; // 当前座位号

        while (true) {
            boolean flag = true;
            for (int school = 1; school <= n; school++) {
                int need = num[school] * 10;
                int[] cur = students.get(school);
                if (cur.length < need) {
                    flag = false;
                    if (seatSchool[cnt - 1] != school) {
                        // 前一个座位不是本校,可以安排
                        seatSchool[cnt] = school;
                        int[] newArr = Arrays.copyOf(cur, cur.length + 1);
                        newArr[cur.length] = cnt;
                        students.set(school, newArr);
                        cnt++;
                    } else {
                        // 前一个是本校,跳到下下个座位
                        seatSchool[cnt + 1] = school;
                        int[] newArr = Arrays.copyOf(cur, cur.length + 1);
                        newArr[cur.length] = cnt + 1;
                        students.set(school, newArr);
                        cnt += 2;
                    }
                }
            }
            if (flag) break;
        }

        StringBuilder sb = new StringBuilder();
        for (int school = 1; school <= n; school++) {
            sb.append("#").append(school).append("\n");
            int[] seats = students.get(school);
            for (int i = 0; i < seats.length; i++) {
                if (i > 0 && i % 10 == 0) sb.append("\n");
                if (i > 0 && i % 10 != 0) sb.append(" ");
                sb.append(seats[i]);
            }
            sb.append("\n");
        }
        System.out.print(sb.toString());
    }
}

Python

python 复制代码
def solve():
    n = int(input())
    num = [0] + list(map(int, input().split()))

    # 记录每个学校学生的座位号
    students = [[] for _ in range(n + 1)]
    id_school = [0] * 100001  # 记录每个座位是哪个学校

    cnt = 1  # 当前座位号

    while True:
        flag = True
        for school in range(1, n + 1):
            # 如果该学校还有学生没安排座位
            if len(students[school]) < num[school] * 10:
                if id_school[cnt - 1] != school:
                    # 前一个座位不是本校,可以安排
                    id_school[cnt] = school
                    students[school].append(cnt)
                    cnt += 1
                else:
                    # 前一个座位是本校,跳到下下个座位
                    id_school[cnt + 1] = school
                    students[school].append(cnt + 1)
                    cnt += 2
                flag = False

        if flag:
            break

    # 输出结果
    for school in range(1, n + 1):
        print(f"#{school}")
        for i, seat in enumerate(students[school]):
            if i > 0 and i % 10 == 0:
                print()
            if i > 0 and i % 10 != 0:
                print(" ", end="")
            print(seat, end="")
        print()

if __name__ == "__main__":
    solve()

运行验证

以样例输入验证:

复制代码
输入:
3
3 4 2

输出:
#1
1 4 7 10 13 16 19 22 25 28
31 34 37 40 43 46 49 52 55 58
61 63 65 67 69 71 73 75 77 79
#2
2 5 8 11 14 17 20 23 26 29
32 35 38 41 44 47 50 53 56 59
62 64 66 68 70 72 74 76 78 80
82 84 86 88 90 92 94 96 98 100
#3
3 6 9 12 15 18 21 24 27 30
33 36 39 42 45 48 51 54 57 60

复杂度分析

  • 时间复杂度:O(T),其中 T 为最终分配的总座位数(不超过 100 × 10 × 10 = 10000)
  • 空间复杂度:O(T),用于存储座位分配结果和临时数组

总结

本题关键在于模拟真实分配过程

  • 同一学校的队员不能相邻 → 需要检查前一个座位
  • 最后只剩一校时隔位就坐 → 检查逻辑自动覆盖这种情况
  • 按学校循环轮转安排 → 类似多路归并的思想

核心是理解"隔位就坐"规则在代码中表现为:若前一个座位已是本校,则当前座位跳过(cnt += 2)。

相关推荐
m0_746752302 小时前
HTML5视频标签针对不同设备DPR的资源选择逻辑
jvm·数据库·python
2301_773553622 小时前
c++怎么在Linux下获取文件被最后一次访问的精确纳秒时间【进阶】
jvm·数据库·python
gmaajt2 小时前
CSS如何给按钮添加按下缩小的动画_利用-active配合transform
jvm·数据库·python
子非鱼@Itfuture2 小时前
ThreadLocal 是什么?如何用?以及最佳使用场景
java·开发语言·spring
杨凯凡2 小时前
【024】JVM 参数入门:堆、栈、元空间与典型模板
java·开发语言·jvm
m0_747854522 小时前
CSS如何让响应式图片在容器内居中_利用background-position
jvm·数据库·python
不懒不懒2 小时前
【PaddleOCR实战指南:图像文字识别、实时摄像头与PyQt5 GUI开发】
开发语言·python
han_hanker2 小时前
下拉模糊搜索多选, 编辑,详情问题
开发语言·javascript·ecmascript
2401_871696522 小时前
CSS如何优化移动端CSS选择器性能_遵循BEM规范避免过长嵌套
jvm·数据库·python