题目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
解题思路
核心规则:
- 从已排名的学生中,找名次最高(数组前端)的未分组学生
- 找名次最低(数组后端)的异性未分组学生
- 两人配对,标记为已分组
- 重复直到所有学生都分组
实现方法:
- 用数组存储所有学生(按输入顺序即为排名顺序)
- 用布尔数组
paired标记已分组学生 - 双指针(或循环遍历)找配对:
- 从前往后找第一个未配对的学生 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人(排名顺序)
| 名次 | 性别 | 姓名 |
|---|---|---|
| 1 | 0 女 | Amy |
| 2 | 1 男 | Tom |
| 3 | 1 男 | Bill |
| 4 | 0 女 | Cindy |
| 5 | 0 女 | Maya |
| 6 | 1 男 | John |
| 7 | 1 男 | Jack |
| 8 | 0 女 | 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)
总结
本题模拟"一帮一"配对过程,关键是理解:每次从前往后取未配对的学生,再从后往前找第一个异性未配对的学生进行配对。