PAT 1095 Cars on Campus

54 篇文章 1 订阅

原文链接:我的个人博客

原题链接

1095 Cars on Campus

考点

思路

  这个题目真的是神烦哦。半夜做真的容易秃发。搞不清楚一个车你要进进出出几次……冷静下来理一理思路。题目中说:进和出都是配对的。只有进没有出的进是无效的,同样的只有出没有进的出也是无效的。这样来说,假如我有一辆A9的车,记录显示8点进入,9点进入,10点进入,下午四点离开。那么合法的时间段就是上午十点到下午四点。
解题的思路来自于柳神。对于hh:mm:ss的时间表示方法利用hh*3600+mm*60+ss化为秒。用vector容器记录输入的每一条记录,包括车牌,时间和进出(进为1,出为-1)。然后根据车牌和时间进行排序。
例如对于题目所给的输入案例,就有

DB8888A 23450   1
DB8888A 46800   -1
JH007BD 18599   1
JH007BD 18633   1
JH007BD 44622   -1
JH007BD 44663   -1
JH007BD 64801   1
JH007BD 65221   -1
ZA133CH 37380   1
ZA133CH 61882   -1
ZA3Q625 23450   1
ZA3Q625 42121   -1
ZA3Q625 86100   1
ZA3Q625 86390   -1
ZD00001 14999   1

合法记录就是车牌相同,且前一个进后一个出的。也就是1、2行4、5行等。
接下来,我们将合法的记录再单独拉个讨论组(用新的vector容器存放)
然后按来的时间顺序进行排序,也就是这样

ZD00001 14999   1
JH007BD 18633   1
DB8888A 23450   1
ZA3Q625 23450   1
ZA133CH 37380   1
ZD00001 41408   -1
ZA3Q625 42121   -1
JH007BD 44622   -1
DB8888A 46800   -1
ZA133CH 61882   -1
JH007BD 64801   1
JH007BD 65221   -1
ZA3Q625 86100   1
ZA3Q625 86390   -1

那么如果我问你05:10:00时刻校园里由多少车,我们只要将其化为秒,然后将小于该时间点的所有记录的flg相加就ok了。不知道这样做会不会超时啊,有点悬。
其实当上面这个列表出来时,我们就可以得到任意一个时间校园里面的车辆了。当然你不需要用数组统计每一个时间点的车俩(我刚开始就是这么想的),只需要统计记录中对应的每一个时间点校园里面的车辆就ok了啊。
最后关于求最长时间的。我们用一个map容器来存放每一个车牌在校园逗留的时间。值得注意的是,车辆可以多次进入校园,需要将时间进行累加。
对于

代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <string>
#include <map>
using namespace std;
struct node {
    char id[10];
    int time, flag = 0;
};
bool cmp1(node a, node b) {
    if(strcmp(a.id, b.id) != 0)
        return strcmp(a.id, b.id) < 0;
    else
        return a.time < b.time;
}
bool cmp2(node a, node b) {
    return a.time < b.time;
}
int main() {
    int n, k, maxtime = -1, tempindex = 0;
    scanf("%d%d\n", &n, &k);
    vector<node> record(n), car;
    for(int i = 0; i < n; i++) {
        char temp[5];
        int h, m, s;
        scanf("%s %d:%d:%d %s\n", record[i].id, &h, &m, &s, temp);
        int temptime = h * 3600 + m * 60 + s;
        record[i].time = temptime;
        record[i].flag = strcmp(temp, "in") == 0 ? 1 : -1;
    }
    sort(record.begin(), record.end(), cmp1);
    map<string, int> mapp;
    for(int i = 0; i < n - 1; i++) {
        if(strcmp(record[i].id, record[i+1].id) == 0 && record[i].flag == 1 && record[i+1].flag == -1) {
            car.push_back(record[i]);
            car.push_back(record[i+1]);
            mapp[record[i].id] += (record[i+1].time - record[i].time);
            if(maxtime < mapp[record[i].id]) {
                maxtime = mapp[record[i].id];
            }
        }
    }
    sort(car.begin(), car.end(), cmp2);
    vector<int> cnt(n);
    for(int i = 0; i < car.size(); i++) {
        if(i == 0)
            cnt[i] += car[i].flag;
         else
            cnt[i] = cnt[i - 1] + car[i].flag;
    }
    for(int i = 0; i < k; i++) {
        int h, m, s;
        scanf("%d:%d:%d", &h, &m, &s);
        int temptime = h * 3600 + m * 60 + s;
        int j;
        for(j = tempindex; j < car.size(); j++) {
            if(car[j].time > temptime) {
                printf("%d\n", cnt[j - 1]);
                break;
            } else if(j == car.size() - 1) {
                printf("%d\n", cnt[j]);
            }
        }
        tempindex = j;
    }
    for(map<string, int>::iterator it = mapp.begin(); it != mapp.end(); it++) {
        if(it->second == maxtime)
            printf("%s ", it->first.c_str());
    }
    printf("%02d:%02d:%02d", maxtime / 3600, (maxtime % 3600) / 60, maxtime % 60);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值