【PAT】1095. Cars on Campus

考查点:排序,模拟题

提交情况:第一次错误,在m次查询过程同时优化和更新最大值冲突,搞了半天才发现,第二次超时,主要没用到m次查询是递增这一条件,这里每次查询不能都把整个数组都遍历一般,数组遍历只需在求最大值时遍历一遍即可,同时记录有效时间段,这样在m次查询整个过程中只需再遍历一遍有效数组

#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#define FOR(i, x, y) for(int i = x; i <= y; i++)
#define rFOR(i, x, y) for(int i = x; i >= y; i--)
#define MAXN 10010
#define oo 0x3f3f3f3f
using namespace std;

struct path{
    int hh,mm,ss;
    bool flag;

}tp,valid[MAXN];
struct car{
    char id[8];
    vector<path> record;
}park[MAXN];
map<string,int> mp;
map<int,string> pm;
int num;
int ans[MAXN];
int flag[MAXN];

vector<int> lastcar;
bool cmpname(car a,car b)
{
    return strcmp(a.id,b.id)<0;
}
bool cmp(path a,path b)
{
    if(a.hh!=b.hh)return a.hh<b.hh;
    else if(a.mm!=b.mm)return a.mm<b.mm;
    else return a.ss<b.ss;
}
int main()
{
     #ifdef LOCAL
        freopen("data.in","r",stdin);
        freopen("data.out","w",stdout);
    #endif // LOCAL
    int n,m;
    string str;
    char ca[25],vis[6];
    scanf("%d%d",&n,&m);

    FOR(i,1,n)
    {
        scanf("%s %d:%d:%d %s",ca,&tp.hh,&tp.mm,&tp.ss,vis);

        str=(string)ca;

        if(strcmp(vis,"in")==0) tp.flag=true;
        else tp.flag=false;
        if(mp.find(str)!=mp.end()){
            park[mp[str]].record.push_back(tp);
        }else{
            mp[str]=num;
            pm[num]=str;
            strcpy(park[num].id,ca);
            park[num].record.push_back(tp);
            num++;

        }
    }
    int last=0;int index;
    sort(park,park+num,cmpname);
    int cnt=0;
    FOR(i,0,num-1)
    for(int j=0;j<park[i].record.size();j++)
    sort(park[i].record.begin(),park[i].record.end(),cmp);

        FOR(i,0,num-1)
        {
            int j=0;
            while(j+1<park[i].record.size())
            {

                while(park[i].record[j].flag!=true && j+1<park[i].record.size())j++;

                if(j==park[i].record.size()-1)break;

                while(park[i].record[j].flag!=false&&j<park[i].record.size())j++;
                if(j==park[i].record.size())break;
                valid[cnt++]=park[i].record[j-1];
                valid[cnt++]=park[i].record[j];
                int res=park[i].record[j].hh*3600+park[i].record[j].mm*60+park[i].record[j].ss;
                res-=park[i].record[j-1].hh*3600+park[i].record[j-1].mm*60+park[i].record[j-1].ss;
                ans[i]+=res;

            }


                if(last<ans[i]){
                    lastcar.clear();
                    last=ans[i];
                    index=i;
                    lastcar.push_back(index);
                }else if(last==ans[i]){
                    lastcar.push_back(i);
                }

        }
    sort(valid,valid+cnt,cmp);
    int cur=0;
    int numcar=0;
    while(m--)
    {
        scanf("%d:%d:%d",&tp.hh,&tp.mm,&tp.ss);
        while(cur<cnt&&cmp(tp,valid[cur])==false){
            if(valid[cur].flag==1)numcar++;
            else numcar--;
            cur++;
        }
        printf("%d\n",numcar);

    }
    for(int i=0;i<lastcar.size();i++)
    {
        printf("%s ",park[lastcar[i]].id);

    }
    printf("%02d:%02d:%02d",last/3600,last%3600/60,last%60);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值