L1-030 一帮一(15分)[java][python]

7 阅读3分钟

题目ID:L1-030 分数:15分 语言:Java / Python

题目描述

"一帮一学习小组"是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。

输入格式

  • 输入第一行给出正偶数 N(≤ 50),即全班学生的人数
  • 此后 N 行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔

保证:本班男女比例是1:1,并且没有并列名次。

输出格式

每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。

样例

输入

8
0 Amy
1 Tom
1 Bill
0 Cindy
0 Maya
1 John
1 Jack
0 Linda

输出

Amy Jack
Tom Linda
Bill Maya
Cindy John

解题思路

核心规则

  1. 从已排名的学生中,找名次最高(数组前端)的未分组学生
  2. 找名次最低(数组后端)的异性未分组学生
  3. 两人配对,标记为已分组
  4. 重复直到所有学生都分组

实现方法

  1. 用数组存储所有学生(按输入顺序即为排名顺序)
  2. 用布尔数组 paired 标记已分组学生
  3. 双指针(或循环遍历)找配对:
    • 从前往后找第一个未配对的学生 A
    • 从后往前找第一个与 A 性别不同且未配对的学生 B
    • 配对输出,并标记两人为已配对

代码实现

Java

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

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine().trim());
        int[] gender = new int[N];
        String[] name = new String[N];
        for (int i = 0; i < N; i++) {
            String[] parts = br.readLine().trim().split("\\s+");
            gender[i] = Integer.parseInt(parts[0]);
            name[i] = parts[1];
        }

        boolean[] paired = new boolean[N];
        for (int i = 0; i < N; i++) {
            if (paired[i]) continue;
            // 找名次最低的异性未配对
            for (int j = N - 1; j >= 0; j--) {
                if (!paired[j] && gender[j] != gender[i]) {
                    paired[i] = true;
                    paired[j] = true;
                    System.out.println(name[i] + " " + name[j]);
                    break;
                }
            }
        }
    }
}

Python

N = int(input())
students = []
for _ in range(N):
    parts = input().split()
    students.append((int(parts[0]), parts[1]))

paired = [False] * N
for i in range(N):
    if paired[i]:
        continue
    # 从后往前找第一个异性未配对
    for j in range(N - 1, -1, -1):
        if not paired[j] and students[j][0] != students[i][0]:
            paired[i] = True
            paired[j] = True
            print(f"{students[i][1]} {students[j][1]}")
            break

运行验证

样例验证

输入:8人(排名顺序)

名次性别姓名
10 女Amy
21 男Tom
31 男Bill
40 女Cindy
50 女Maya
61 男John
71 男Jack
80 女Linda

配对过程

  • 第1名 Amy(女) → 找最后一名异性:Linda(女❌) → John(男✓) → Amy John
  • 第2名 Tom(男) → 找最后一名未配对异性:Linda(女✓) → Tom Linda
  • 第3名 Bill(男) → 找最后一名未配对异性:Cindy(女✓) → Bill Maya
  • 第4名 Cindy(女) → 找最后一名未配对异性:John(已配对❌) → Cindy John

等等,输出样例是:

Amy Jack
Tom Linda
Bill Maya
Cindy John

让我重新检查:

  • 第1名 Amy(女) → 从后往前找未配对异性:Linda(女❌) → John(男✓) → Amy Jack(John不是Jack...)

实际上顺序应该是:Bill(男) 和 Maya(女) 是一对。让我再看一遍输入数据...

哦,我发现题目说的是名次最低的异性,而样例输出是:

Amy Jack   # 第1女 vs 第7男
Tom Linda  # 第2男 vs 第8女
Bill Maya  # 第3男 vs 第5女
Cindy John # 第4女 vs 第6男

即:排名靠前的学生与排名靠后的异性学生配对。

复杂度分析

  • 时间复杂度:O(N²),最坏情况每次查找 O(N),共 N/2 次配对
  • 空间复杂度:O(N)

总结

本题模拟"一帮一"配对过程,关键是理解:每次从前往后取未配对的学生,再从后往前找第一个异性未配对的学生进行配对。