1. 题目分析与解题思路
1.1 问题背景与需求理解
这道题目来源于PTA团体程序设计天梯赛,编号L2-028,题目名为"秀恩爱分得快"。题目要求我们通过分析一组照片数据,计算人与人之间的亲密度,并判断给定的一对情侣是否存在比对方更亲密的异性朋友。
核心需求可以分解为:
- 计算每个人与所有异性的亲密度
- 找出每个人亲密度最高的异性
- 判断这对情侣是否互为最亲密的异性
- 按要求格式输出结果
1.2 输入输出分析
输入格式分为三部分:
- 第一行:总人数N和照片数M
- 接下来M行:每张照片中的人员列表
- 最后一行:待分析的一对情侣编号
输出要求:
- 如果这对情侣互为最亲密异性,则只输出他们两人
- 否则分别输出每个人最亲密的异性(可能有多个并列)
1.3 算法设计思路
这道题的核心在于高效计算亲密度。直接暴力计算的时间复杂度是O(M*K²),对于N=1000,M=1000,K=500的情况,这样的复杂度显然无法在500ms内完成。
优化思路是:
- 建立"人→照片"的倒排索引,这样计算某个人的亲密度时,只需要遍历他出现过的照片
- 在每张照片中,只计算与目标人物性别不同的成员
- 使用浮点数比较时的容错机制(1e-9)
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 关键数据结构与实现细节
2.1 性别存储与处理
由于题目中女性编号前有负号,但0和-0在数值上相同,需要特殊处理。我们使用boolean数组isFemale来存储性别信息:
java复制boolean[] isFemale = new boolean[1000];
读取ID时,通过判断首字符是否为'-'来设置性别标志:
java复制public int[] nextID() throws Exception {
int c = read();
while (c >= 0 && c <= 32) c = read();
int gender = 0;
if (c == '-') {
gender = 1; // 标记为女性
c = read();
}
int res = 0;
while (c >= '0' && c <= '9') {
res = res * 10 + (c - '0');
c = read();
}
return new int[]{res, gender};
}
2.2 链式前向星索引
为了高效查询每个人参与的照片,我们使用链式前向星数据结构建立倒排索引:
java复制static int[] head = new int[1000]; // 每个人对应的第一条边
static int[] nextArr = new int[500005]; // 下一条边的索引
static int[] photoIndex = new int[500005]; // 照片索引
static int edgeCount = 0; // 当前边数
添加索引的逻辑:
`
