九度OJ 1013 开门人和关门人

本文介绍了一种算法,用于处理机房人员的签到签离记录,通过分析这些记录来确定每天最早开门和最晚关门的人。文章详细解释了如何比较时间序列,并提供了一个具体的C++实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
    每天第一个到机房的人要把门打开,最后一个离开的人要把门关好。现有一堆杂乱的机房签到、签离记录,请根据记录找出当天开门和关门的人。
输入:

    测试输入的第一行给出记录的总天数N ( N> 0 ),下面列出了N天的记录。 
    每天的记录在第一行给出记录的条目数M (M > 0 ),下面是M行,每行的格式为 

    证件号码 签到时间 签离时间 

    其中时间按“小时:分钟:秒钟”(各占2位)给出,证件号码是长度不超过15的字符串。

输出:

    对每一天的记录输出1行,即当天开门和关门人的证件号码,中间用1空格分隔。 
    注意:在裁判的标准测试输入中,所有记录保证完整,每个人的签到时间在签离时间之前,且没有多人同时签到或者签离的情况。

样例输入:
3
1
ME3021112225321 00:00:00 23:59:59
2
EE301218 08:05:35 20:56:35
MA301134 12:35:45 21:40:42
3
CS301111 15:30:28 17:00:10
SC3021234 08:00:00 11:25:25
CS301133 21:45:00 21:58:40
样例输出:
ME3021112225321 ME3021112225321
EE301218 MA301134
SC3021234 CS301133

题目意思很好理解,就是求这些人中开门时间最早的那人的编号,关门最晚的那人的编号。
有两点要注意:1.如何比较时间的大小,即根据输入的时间序列判断时间的先后次序  2.如何按行输入,根据空格拆分字符串,还有cin.ignore()忽略掉换行符都是一些易忽视的细节
具体实现:首先将第一个人的信息作为开门最早和关门最晚,然后每处理一个字符串,就根据开门时间关门时间,更新开门最早的人和关门最晚的人。


#include <iostream>
using namespace std;

bool compare_time(string str1,string str2){
    int hour1,minute1,second1,hour2,minute2,second2;
    hour1 = (str1[0] - '0')*10 + (str1[1] - '0');
    hour2 = (str2[0] - '0')*10 + (str2[1] - '0');
    if(hour1 > hour2)
        return 1;
    if(hour1 < hour2)
        return 0;
    if(hour1 == hour2){
        minute1 = (str1[3] - '0')*10 + (str1[4] - '0');
        minute2 = (str2[3] - '0')*10 + (str2[4] - '0');
        if(minute1 > minute2)
            return 1;
        if(minute1 < minute2)
            return 0;
        if(minute1 == minute2){
            second1 = (str1[6] - '0')*10 + (str1[7] - '0');
            second2 = (str2[6] - '0')*10 + (str2[7] - '0');
            if(second1 > second2)
                return 1;
            else
                return 0;
        }
    }
    return 0;
}

int main(){
    int n,m;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>m;
        cin.ignore();  //把最后的换行符忽略掉
        string str,name,open_time,close_time;
        string earlist_open_time,earlist_name,latest_close_time,latest_name;
        getline(cin,str);
        int index1 = str.find(" ");
        int index2 = str.rfind(" ");
        name = str.substr(0,index1);
        earlist_name = latest_name = name;
        open_time = str.substr(index1+1,index2-index1);
        earlist_open_time = open_time;
        close_time = str.substr(index2+1,str.length()-index1);
        latest_close_time = close_time;
        for(int i=0;i<m-1;i++){
            getline(cin,str);
            index1 = str.find(" ");
            index2 = str.rfind(" ");
            name = str.substr(0,index1);
            open_time = str.substr(index1+1,index2-index1);
            close_time = str.substr(index2+1,str.length()-index1);
            if(compare_time(earlist_open_time,open_time)){
                earlist_open_time = open_time;
                earlist_name = name;
            }
            if(compare_time(close_time,latest_close_time)){
                latest_close_time = close_time;
                latest_name = name;
            }
        }
        cout<<earlist_name<<" "<<latest_name<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值