PAT 1095 Cars on Campus

给出n个汽车的出入记录,给出k个询问,每次询问时间,求该时间点停车场的停车数量。最后输出停车总时长最长的车,输出车牌,如果有多辆就按字母顺序输出结果,最后输出总时长。出入记录要有in和out成对出现才有效,一辆车连续多次in,取最后一次,连续多次out,取第一次。
这一题,用map将字符串名称与数组下标对应起来,将时间转化为数字,先把所有记录排序,再将对应的有效记录分配给不同的车子,根据每辆车的当前出入情况判断:
1、当前为in,如果所有记录中当前为in,则删除车子中的这一条记录,将最新记录加入。
(导致可能存在只有一条in记录的情况)
2、当前为out,如果所有记录中当前为in,则将新记录加入。(导致可能存在最后一条是in的情况)
一开始是每次询问就遍历一遍,一提交发现第五个测试点超时了,后来改用一个数组记录每一秒停车场的车数,每次询问直接给出结果,提交后,第五个测试点错误,弄了很久才发现,是没有完全排除无效数据,可能存在in后就没有out,遍历车子出入记录时,将数量大小为奇数的减一或者将最后一条记录删除。
有一种做法比较好 ,将所有有效数据放到一个数组中,将每一条记录的停车数计算出来,这样可以不用直接开八万多的数组记录每一秒的车辆,可以减少开销,不过要遍历比较才可以找到想要的结果,计算最长时间就感觉麻烦一点了。
(用时:2:26:53.51)

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
//#include <bits/stdc++.h>
using namespace std;
struct Records {
    int plateNumber;
    int time;
    int status;
};
bool cmp(Records a,Records b)
{
    return a.time < b.time;
}


int main()
{
    int n,k;

    scanf("%d%d",&n,&k);
    string pNumber;
    char statusStr[4];
    int hour,minute,second;
    map<string,int> numToIndex;
    map<int,string> indexToNum;
    int length = 0;
    int index = 0;
    vector<Records> recordsVec;
    for(int i=0; i<n; i++) {
        cin>>pNumber;
        scanf("%d:%d:%d %s",&hour,&minute,&second,statusStr);
        if(numToIndex.count(pNumber)==0) {
            index = length;
            numToIndex[pNumber] =length;
            indexToNum[length] = pNumber;
            length++;
        }

        index = numToIndex[pNumber];
        Records record;
        record.plateNumber = index;
        record.time=hour*60*60+minute*60+second;
        switch(statusStr[0]) {
        case 'i':
            record.status = 1;
            break;
        case 'o':
            record.status = 0;
            break;
        default:
            break;
        }
        recordsVec.push_back(record);
    }

    sort(recordsVec.begin(),recordsVec.end(),cmp);
    vector<Records> carRecords[length];
    Records r;
    int s;

    for(int i=0; i<recordsVec.size(); i++) {
    	//第一条记录一定是in
        if(carRecords[recordsVec[i].plateNumber].size()==0) {
            if(recordsVec[i].status==1) {
                carRecords[recordsVec[i].plateNumber].push_back(recordsVec[i]);
            }
        } else {
            s = carRecords[recordsVec[i].plateNumber].size();
            r = carRecords[recordsVec[i].plateNumber][s-1];
            //车辆当前的记录是in
            if(r.status==1) {
            //又是in,相同,删除原来的in记录
                if(recordsVec[i].status==1) {
                    carRecords[recordsVec[i].plateNumber].erase(carRecords[recordsVec[i].plateNumber].begin()+s-1);
                }
                carRecords[recordsVec[i].plateNumber].push_back(recordsVec[i]);
            } else {  //车辆当前的记录是out
            //是in,加入
                if(recordsVec[i].status==1) {
                    carRecords[recordsVec[i].plateNumber].push_back(recordsVec[i]);
                }
            }
        }
    }
    int time = 0;
    int carNum = 0;
    int carNumFt[86401]= {0};
    for(int i=0; i<length; i++) {
        s = carRecords[i].size();
        if(s%2==1) {
        //数量大小是奇数,删除最后一条记录
            carRecords[i].pop_back();
            s--;
        }
        for(int j=0; j<s; j++) {
            switch(carRecords[i][j].status) {
            case 1:
            //有in 相应时间点的车辆数+1
                carNumFt[carRecords[i][j].time]++;
                break;
            case 0:
                carNumFt[carRecords[i][j].time]--;
                break;
            default:
                break;
            }
        }
    }

    for(int i=1; i<86401; i++) {
        carNumFt[i] += carNumFt[i-1];
    }

    for(int t=0; t<k; t++) {
        scanf("%d:%d:%d",&hour,&minute,&second);
        carNum = 0;
        time = hour * 60 *60 + minute * 60 + second;
        printf("%d\n",carNumFt[time]);
    }

    int cost[length] = {0};
    for(int i=0; i<length; i++) {
        s = carRecords[i].size();
        for(int j=0; j<s; j+=2) {
            cost[i] += carRecords[i][j+1].time - carRecords[i][j].time;
        }
    }

    int maxNum = cost[0];
    for(int i=1; i<length; i++) {
        if(maxNum < cost[i]) {
            maxNum =cost[i];
        }
    }
    vector<string> longestTimeCar;
    for(int i=0; i<length; i++) {
        if(maxNum == cost[i]) {
            longestTimeCar.push_back(indexToNum[i]);
        }
    }

    sort(longestTimeCar.begin(),longestTimeCar.end());

    for(int i=0; i<longestTimeCar.size(); i++) {
        if(i==0) {
            cout<<longestTimeCar[i];
        } else {
            cout<<" "<<longestTimeCar[i];
        }

    }

    hour = maxNum/(60*60);
    minute = maxNum %(60*60) /60;
    second = maxNum %60;
    printf(" %02d:%02d:%02d\n",hour,minute,second);

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值