PAT A1095 Cars on Campus [排序+硬核模拟]

题目描述

链接

题意:
给出n个车牌号、时间点、进出状态的记录,然后查询k个时间点这时校园内的车辆个数。最后还要输出在校园里面呆的时间最长的车的车牌号,以及呆了多久的时间。如果有多辆车就按照它的字母从小到大输出车牌。

注意:输出的是呆的最久的车牌,不是说在某时刻前呆的最久的

分析

  • 时间问题的模拟,将时间转为秒数
  • 用结构体存储输入的每条记录,再从中筛选,把合法的挑出来放在另一个集合里面。不需要!!一次就完成输入和筛选
  • 筛选的方法是:对原记录进行排序,先按照车牌号排序,再按照来的时间先后排序。能根据这样的排序后的顺序将所有满足条件(合法)的车辆进出记录保存到另一个数组里面。这个数组再按照时间先后排序!!!一定记住这一点!!
  • 配对的要求:flag = 1/-1,之所以是这个值,因为对其求和就可以知道某个时间点的车辆数
  • cnt[i]表示在i下标的记录的时间点的时候车辆的数量。数量可以由前一个数量+当前车辆的flag得到
  • 一个车可能出入校园好多次,停车的时间应该取之和
  • 注意用map保存的是某个车的停留时间,至于某时刻的车辆数量!!!不需要cnt[time],直接将下标换成记录的下标!!!
  • 如果上一个查询的index已经被记住,那么下一次就只需要从这个index开始找就可以了,避免重复寻找,浪费时间

代码

#include<bits/stdc++.h>
using namespace std;

struct node{
    char id[20];
    int num;
    int flag;
};

int n,k; 

bool cmp1(node a, node b){
    if(strcmp(a.id, b.id) != 0) return strcmp(a.id, b.id) < 0;
    return a.num < b.num;
}

bool cmp2(node a, node b){
    return a.num < b.num;
}

int main(){
    scanf("%d%d",&n,&k);
    vector<node> rec(n), car;
    //保存所有数据
    for(int i=0;i<n;i++){
        int hh,mm,ss; char s[20];
        scanf("%s %d:%d:%d %s", rec[i].id, &hh, &mm, &ss, s);
        rec[i].num = hh*3600 + mm * 60 + ss;
        rec[i].flag = strcmp(s, "in") == 0 ? 1:-1;
    }
    //从中筛选出合法的,放进另一个数组
    sort(rec.begin(), rec.end(), cmp1); //将id相同的车按时间先后放一起
    //用map数组保存每次某辆进出时的停留时间的和,记得加起来
    map<string, int> mp;
    int maxtime = -1;
    //合法的必定是一进一出的
    for(int i=0;i<n-1;i++){
        if(strcmp(rec[i].id, rec[i+1].id) == 0 && rec[i].flag == 1 && rec[i+1].flag == -1){
            car.push_back(rec[i]);
            car.push_back(rec[i+1]);
            mp[rec[i].id] += (rec[i+1].num - rec[i].num);
            if(maxtime < mp[rec[i].id]) maxtime = mp[rec[i].id];
        }
    }
    //再按时间先后顺序排序
    sort(car.begin(), car.end(), cmp2);
    vector<int> cnt(n);
    //flag 设置为1,-1的好处
    //cnt[i]表示在i下标的记录的时间点的时候车辆的数量, 我之前直接用的num存,不对,应该用记录的id
    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;
    }
    //查询
    int tempindex = 0; //下一次查询是从上一次查询位置开始向下找
    while(k--){
        int hh,mm,ss;
        scanf("%d:%d:%d", &hh, &mm, &ss);
        int temptime = hh*3600 + mm * 60 + ss;
        int j;
        for(j=tempindex; j<car.size(); j++){
            if(car[j].num > temptime){ //找到了
                printf("%d
", cnt[j-1]);
                break;
            }else if(j == car.size() - 1){ //找到末尾了
                printf("%d
", cnt[j]);
            }
        }
        tempindex = j;
    }
    for(auto it=mp.begin(); it!=mp.end(); it++){
        if(it->second == maxtime){
            printf("%s ", it->first.c_str());
        }
    }
    printf("%02d:%02d:%02d
", maxtime/3600, maxtime%3600/60, maxtime%60);
}
原文地址:https://www.cnblogs.com/doragd/p/11463228.html