**PAT浙大甲级 1095

这个题很注重时间复杂性,我是用map<string,vector<node> >来存每一个号码的车的记录。对每个不同号码的车将不有效的记录删除,然后添加到vector<node>中,同时统计不同号码的车一天内停车的总时间,并加结果添加到vector<nod>中,然后对vector<node>进行排序,注意题目中是按照时间的递增进行查询,因此在进行某次查询时,从上一次查询中断的位置开始进行查询,输出结果。最后对vector<nod>进行排序,输出停车时间最长的车号(按字典序) 以及停车时间。

AC代码:

#include<iostream>
#include<map>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<set>
#include<stack>
#include<cmath>
#include<vector>
#include<hash_map>
#define ll long long
#define inf 24*60*60
using namespace std;
struct node
{
    string id;
    int time;
    int state;
};
struct nod
{
    string id;
    int sum;
};
vector<node> v;
bool cmp(node x,node y)
{
    return x.time<y.time;
}
bool cmp1(nod x,nod y)
{
    if(x.sum!=y.sum)
    {
        return x.sum>y.sum;
    }
    else
    {
        return x.id<y.id;
    }
}
map<string,int> nn;
map<string,vector<node> >mm;
vector<nod> vv;
int main()
{
    int n,k;
    scanf("%d %d",&n,&k);
    for(int i=0;i<n;i++)
    {
        node tmp;
        cin>>tmp.id;
        int a,b,c;
        char sta[5];
        scanf("%d:%d:%d %s",&a,&b,&c,sta);
        int time=a*3600+b*60+c;
        tmp.time=time;
        if(sta[0]=='i')
        {
            tmp.state=1;
        }
        else
        {
            tmp.state=-1;
        }
        mm[tmp.id].push_back(tmp);
        nn[tmp.id]=0;
    }
    map<string,vector<node> >::iterator it;
    for(it=mm.begin();it!=mm.end();it++)
    {
        sort(it->second.begin(),it->second.end(),cmp);
        stack<node> ss;
        int sum=0;
        int len=it->second.size();
        for(int i=0;i<len;i++)
        {
            if(it->second[i].state==1)
            {
                if(ss.empty())
                {
                    ss.push(it->second[i]);
                }
                else
                {
                    ss.pop();
                    ss.push(it->second[i]);
                }
            }
            else
            {
                if(ss.empty())
                {
                    continue;
                }
                else
                {
                        node tmp=ss.top();
                        ss.pop();
                        int r=it->second[i].time;
                        v.push_back(tmp);
                        v.push_back(it->second[i]);
                        sum+=r-tmp.time;
                }
            }
        }
        nod tt;
        tt.id=it->first;
        tt.sum=sum;
        vv.push_back(tt);
    }
    sort(v.begin(),v.end(),cmp);
    int len=v.size();
    int biao=0;
    int ans=0;
    for(int i=0;i<k;i++)
    {
        int a,b,c;
        scanf("%d:%d:%d",&a,&b,&c);
        int time=a*3600+b*60+c;
        int re=ans;
        for(int j=biao;j<len;j++)
        {
            if(v[j].time>time)
            {
                biao=j;
                ans=re;
                break;
            }
            else
            {
                int t=nn[v[j].id];
                if(t+v[j].state==1)
                {
                    re++;
                    nn[v[j].id]++;
                }
                else if(t+v[j].state==0)
                {
                    re--;
                    nn[v[j].id]--;
                }
            }
        }
        printf("%d\n",re);
    }
    sort(vv.begin(),vv.end(),cmp1);
    int maxx=vv[0].sum;
    for(int i=0;i<vv.size();i++)
    {
        if(vv[i].sum==maxx)
        {
            cout<<vv[i].id<<" ";
        }
        else
        {
            break;
        }
    }
    int xiaoshi=maxx/3600;
    int fen=(maxx%3600)/60;
    int miao=maxx%60;
    printf("%02d:%02d:%02d",xiaoshi,fen,miao);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值