• 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);
    }
    
  • 相关阅读:
    6种负载均衡算法
    Java中volatile关键字
    剑指offer练习
    linux系统查看IP地址,不显示IP地址或者只显示127.0.0.1
    Nginx负载均衡配置
    集群应用Session一致性实现的三种方案
    rabbitMQ学习
    JDK1.8在LINUX下安装步骤
    ecplise部署gradle web项目
    Kubernetes下的应用监控解决方案
  • 原文地址:https://www.cnblogs.com/doragd/p/11463228.html
Copyright © 2020-2023  润新知