> 技术文档 > PAT 甲级题目讲解:1006《Sign In and Sign Out》

PAT 甲级题目讲解:1006《Sign In and Sign Out》


✅ PAT 甲级题目讲解:1006《Sign In and Sign Out》

–B站讲解视频:火烤小布丁-PAT 甲级题目讲解
–讲义 GitHub 地址 持续免费更新中…
祝大家刷题顺利,愉快学算法!有问题建议也欢迎留言~
感谢点赞收藏,欢迎关注支持

🧩 题目简介

本题模拟校园机房打卡记录:

  • 每天 最早 签到的人 解锁 电脑房
  • 每天 最晚 签出的人锁门

给定一组人员打卡记录,输出当天“解锁者”与“锁门者”的 ID。


🧪 样例分析

输入样例:

3CS301111 15:30:28 17:00:10SC3021234 08:00:00 11:25:25CS301133 21:45:00 21:58:40

分析:

  • SC3021234 最早签到,是解锁者;
  • CS301133 最晚签出,是锁门者;

输出为:

SC3021234 CS301133

🔍 解题思路

本题为字符串输入 + 时间转换 + 比较最值的经典模拟题。

我们将时间统一转换为“当日第多少秒”,以便于比较。


📎 变量说明

变量名 含义 m 记录条数 t 当前读入的 ID hh, mm, ss 小时、分钟、秒(作为临时变量) ulk 最早签到者 ID(unlock) lk 最晚签出者 ID(lock) mint 当前最小时间(初始化为 INT_MAX) maxt 当前最大时间(初始化为 INT_MIN)

✅ Step 1:时间格式转换为秒

int cal(){ scanf(\"%d:%d:%d\", &hh, &mm, &ss); int s = hh * 60 * 60 + mm * 60 + ss; // 转换为当天第 s 秒 return s;}

✅ Step 2:遍历记录找最小/最大时间

int mint = INT_MAX, maxt = INT_MIN;while(m--){ cin >> t; int t1 = cal(); // 签到时间 if(t1 < mint){ mint = t1; ulk = t; } int t2 = cal(); // 签出时间 if(t2 > maxt){ maxt = t2; lk = t; }}

✅ 完整代码

#includeusing namespace std;int m, hh, mm, ss;string t, ulk, lk;int cal(){ scanf(\"%d:%d:%d\", &hh, &mm, &ss); int s = hh * 60 * 60 + mm * 60 + ss; // 转换为一天中第 s 秒 return s;}int main(){ cin >> m; int mint = INT_MAX, maxt = INT_MIN; while(m--){ cin >> t; int t1 = cal(); // 签到时间 if(t1 < mint){ mint = t1; ulk = t; } int t2 = cal(); // 签出时间 if(t2 > maxt){ maxt = t2; lk = t; } } cout << ulk << \" \" << lk; return 0;}

🚧 常见错误提醒

错误类型 错误表现 ❌ 时间转换错误 将 hh 写成 hh * 60,少乘一次 60,结果不对 ❌ 忘记使用 INT_MAX / INT_MIN 初始值设置不当会导致比较错误 ⚠️ scanfcin 混用不当 若不匹配顺序,可能读取错行

✅ 总结归纳

  • 本题核心是字符串格式解析 + 比较最值
  • 统一单位(秒)是关键建模步骤;
  • 注意时间格式处理和转换成秒的计算的准确性;

🧠 思维拓展

  • 本题其实也可以直接用字符串比较完成;
  • 若时间数据是乱序输入,当前方法也适用;