HDU1234 开门人和关门人【水题】

开门人和关门人

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 17861    Accepted Submission(s): 9056


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

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

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

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

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

Sample Input
  
  
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
 

Sample Output
  
  
ME3021112225321 ME3021112225321 EE301218 MA301134 SC3021234 CS301133
 

Source


问题链接HDU1234 开门人和关门人

问题简述:参见上文。

问题分析

  这个问题不是很困难,还是可以锻炼人处理输入输出的能力。

程序说明

  这个问题有两种解法:


  一是排序:  

  解决问题时,做两个排序,就可以找出开门的人和关门的人。程序中时间转换为整数(秒单位),以便比较排序。这里同时给出C和C++的程序。

  C和C++的排序库程序不一样,分别是qsort()和sort,参数不同,比较程序形式上也不一样。

  一些细节还是需要注意的,C++程序中的比较函数,参数是常量和引用。

  另外,在出来格式化输入方面,还是C语言有优势,所以C++程序中使用C语言的代码处理输入。

  

  二是同时进行输入计算:

  程序一边读入数据一边计算开门人和关门人,省去结构数组,是最佳解法。

  程序中时间转换为整数(秒单位),以便比较。


AC通过的C语言程序如下(第2种方法):

/* HDU1234 开门人和关门人 */

#include <stdio.h>
#include <string.h>

int main()
{
    int n, m;
    int h, mi, s;

    char startname[20];
    char endname[20];
    int minstarttime;
    int maxendtime;

    char name[20];
    int starttime;
    int endtime;

    // 读入总天数(测试组数)
    scanf("%d", &n);
    while(n--) {
        // 读入记录数
        scanf("%d", &m);

        // 设置暂时的最小开门时间和最大关门时间
        minstarttime = 24 * 3600;
        maxendtime = 0;

        // 读入各个记录,并且求最小开门时间和最大关门时间
        for(int i=1; i<=m; i++) {
            scanf("%s %d:%d:%d", name, &h, &mi, &s);
            starttime = s + mi * 60 + h * 3600;
            if(starttime < minstarttime) {
                minstarttime = starttime;
                strcpy(startname, name);
            }

            scanf("%d:%d:%d", &h, &mi, &s);
            endtime = s + mi * 60 + h * 3600;
            if(endtime > maxendtime) {
                maxendtime = endtime;
                strcpy(endname, name);
            }
        }

        // 输出结果
        printf("%s %s\n", startname, endname);
    }

    return 0;
}


AC通过的C语言程序如下(排序):

/* HDU1234 开门人和关门人 */

#include <stdio.h>
#include <stdlib.h>

struct node
{
    char name[20];
    int starttime;
    int endtime;
} record[1000];

int cmp1(const void * a, const void * b)
{
    struct node *x = (struct node *) a;
    struct node *y = (struct node *) b;
    return x->starttime - y->starttime;
}

int cmp2(const void * a, const void * b)
{
    struct node *x = (struct node *) a;
    struct node *y = (struct node *) b;
    return y->endtime - x->endtime;
}

int main(void)
{
    int n, m, i;
    int h, mi, s;

    // 读入总天数(测试组数)
    scanf("%d", &n);
    while(n--) {
        // 读入记录数
        scanf("%d", &m);
        // 读入各个记录
        for(i=0; i<m; i++) {
            scanf("%s %d:%d:%d", record[i].name, &h, &mi, &s);
            record[i].starttime = s + mi * 60 + h * 3600;
            scanf("%d:%d:%d", &h, &mi, &s);
            record[i].endtime = s + mi * 60 + h * 3600;
        }

        // 排序(按开门时间)
        qsort(record, m, sizeof(record[0]), cmp1);
        // 输出开门人名字
        printf("%s ",record[0].name);
        // 排序(按关门时间)
        qsort(record, m, sizeof(record[0]), cmp2);
        printf("%s\n",record[0].name);
    }

    return 0;
}

AC通过的C++语言程序如下(排序):
/* HDU1234 开门人和关门人 */

#include <iostream>
#include <algorithm>
#include <cstdio>

using namespace std;

struct node
{
    char name[20];
    int starttime;
    int endtime;
} record[1000];

bool cmp1(const node& a, const node& b)
{
    return a.starttime < b.starttime;
}

bool cmp2(const node& a, const node& b)
{
    return a.endtime > b.endtime;
}

int main()
{
    int n, m;
    int h, mi, s;

    // 读入总天数(测试组数)
    cin >> n;
    while(n--) {
        // 读入记录数
        cin >> m;

        // 读入各个记录
        for(int i=0; i<m; i++) {
            scanf("%s %d:%d:%d", record[i].name, &h, &mi, &s);
            record[i].starttime = s + mi * 60 + h * 3600;
            scanf("%d:%d:%d", &h, &mi, &s);
            record[i].endtime = s + mi * 60 + h * 3600;
        }

        // 排序(按开门时间)
        sort(record, record + m, cmp1);
        // 输出开门人名字
        cout << record[0].name << " ";
        // 排序(按关门时间)
        sort(record, record + m, cmp2);
        cout << record[0].name << endl;
    }

    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值