编写程序计算银行客户最长停留时长(分钟)技术问询
解决银行客户最长停留时长计算问题
看起来你写的代码离正确解决问题还有不少距离,我来帮你梳理问题、修正错误并给出可行的解决方案。
问题回顾
需编写程序计算客户在银行的最长停留时长(单位:分钟)。
输入规范
标准输入第一行包含事件数量N(1≤N≤100)和时间X(1≤X≤23)。后续N行每行含4个空格分隔的整数:
- 事件时间小时部分(0≤H≤23)
- 事件时间分钟部分(0≤M≤59)
- 事件类型:1为进入,-1为离开,-2为取款,2为存款
- 正整数(1≤S≤10000000):卡号或金额(依事件类型而定)
输出规范
标准输出第一行输出客户在银行的最长停留时长(分钟)。
示例输入(修正笔误后)
7 11 10 1 1 12345 11 50 -2 10000 12 10 -1 12345 23 10 1 24680 23 11 -2 5000 23 15 1 13579 23 20 1 98765
注:你提供的原始示例输入中第二行缺少事件类型字段,这里修正为符合规范的格式。
示例输出
129
计算逻辑:客户12345在10:01进入,12:10离开,时长为 (1260+10)-(1060+1) = 129分钟。
现有代码的问题
- 输入处理错误:第一行需要读取N和X两个整数,但你的代码只读取了
row(即N),导致后续所有事件数据的读取全部错位,直接导致逻辑完全错误。 - 数组定义不规范:标准C++不支持用变量
row定义静态数组int time[row][col],这是非标准的变长数组特性,在多数编译器中会报错,应该使用vector等动态容器。 - 核心逻辑错误:
- 循环从
i=1开始并访问time[i+1],会触发数组越界(数组索引从0开始,最大索引为row-1)。 - 未区分事件类型,错误地将取款/存款事件的金额与卡号混淆,导致判断逻辑完全失效。
- 计算时长时只考虑小时差,完全忽略分钟部分,也未处理跨天的情况(比如23:50进入、次日0:10离开的场景)。
- 循环从
正确的解决方案
思路
- 将所有事件时间转换为总分钟数(
H*60 + M),简化时长计算。 - 使用哈希表(
unordered_map)记录每个客户的进入时间,键为卡号,值为进入的总分钟数。 - 遍历每个事件:
- 若为进入事件(类型1):记录该卡号的进入时间。
- 若为离开事件(类型-1):计算当前时间与进入时间的差值,若跨天则加上24*60分钟,更新最长停留时长。
- 取款(-2)和存款(2)事件不影响停留状态,直接跳过。
- 最终输出最长停留时长,若无客户离开则输出0。
正确代码
#include <iostream> #include <unordered_map> #include <vector> using namespace std; int main() { int N, X; cin >> N >> X; // 读取第一行的事件数N和时间X // 用vector存储所有事件,避免非标准变长数组问题 vector<vector<int>> events(N, vector<int>(4)); for (int i = 0; i < N; ++i) { cin >> events[i][0] >> events[i][1] >> events[i][2] >> events[i][3]; } unordered_map<int, int> enterTime; // 键:卡号,值:进入时间(总分钟数) int longestStay = 0; for (const auto& event : events) { int H = event[0]; int M = event[1]; int type = event[2]; int val = event[3]; int currentTime = H * 60 + M; if (type == 1) { // 记录客户进入时间 enterTime[val] = currentTime; } else if (type == -1) { // 计算客户停留时长 auto it = enterTime.find(val); if (it != enterTime.end()) { int stayTime; if (currentTime >= it->second) { stayTime = currentTime - it->second; } else { // 处理跨天情况,加上24小时的分钟数 stayTime = (currentTime + 24 * 60) - it->second; } // 更新最长停留时长 if (stayTime > longestStay) { longestStay = stayTime; } enterTime.erase(it); // 移除已离开客户的记录,避免重复计算 } } // 取款、存款事件直接跳过 } cout << longestStay << endl; return 0; }
代码说明
- 使用
vector<vector<int>>存储事件,符合标准C++规范,避免了变长数组的兼容性问题。 unordered_map提供O(1)级别的查找效率,快速定位客户的进入时间。- 处理了跨天的边界情况,确保时长计算准确。
- 离开事件后移除客户记录,防止同一客户多次进出时的错误计算。
内容的提问来源于stack exchange,提问作者Katz Trill
相关产品推荐
相关产品推荐

