题意: 给出n个车牌号、时间点、进出状态的记录,然后查询k个时间点这时校园内的车辆个数。最后还要输出在校园里面呆的时间最长的车的车牌号,以及呆了多久的时间。如果有多辆车就按照它的字母从小到大输出车牌。
配对要求是,如果一个车多次进入未出,取最后一个值;如果一个车多次out未进入,取第一个值。
注意:一个车可能出入校园好多次,停车的时间应该取之和。
tip:map+排序+状态记录
#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
struct ss {
string time;
string state;
};
bool cmp(struct ss a,struct ss b) {
return a.time<b.time;
}
bool cmp1(pair<string,int>a,pair<string ,int>b) {
if(a.second==b.second)
return a.first<b.first;
else return a.second>b.second;
}
int gettime(string time) {
return stoi(time.substr(0,2))*3600+stoi(time.substr(3,2))*60+stoi(time.substr(6,2));
}
int main() {
int n,m;
scanf("%d %d\n",&n,&m);
map<string ,int> ltime;
map<string,vector<struct ss>>s;
char name[100],time[30],state[10];
for(int i=0; i<n; ++i) {
scanf("%s %s %s\n",name,time,state);
s[name].push_back({time,state});//按照车牌号将所有记录一并打包先
}
int ans[86403]= {0};//记录每时刻的停车车辆
for(auto i=s.begin(); i!=s.end(); ++i) {
sort((*i).second.begin(),(*i).second.end(),cmp);//每辆车记录时间排序
vector<struct ss> temp;
int t=0;
ltime[(*i).first]=0;
while(t<(*i).second.size()&&(*i).second[t].state=="in")//选择最晚的 in
t++;
if(t)
t--;
if(t<(*i).second.size())
temp.push_back((*i).second[t]);//暂时存在 in,与下一个out配对
ltime[(*i).first]=0;
for(int j=t+1; j<(*i).second.size(); ++j)
if(temp.size()&&(*i).second[j].state!=temp[0].state&&(*i).second[j].time!=temp[0].time) {
if(temp[0].state=="in") {//状态转换时,由in到out
int a=gettime(temp[0].time);
int b=gettime((*i).second[j].time);
ltime[(*i).first]+=b-a;//记录停车时间
for(int k=a; k<b; ++k)
ans[k]++;//停车区间++
}
temp.pop_back();
temp.push_back((*i).second[j]);//交换状态
} else if(temp[0].state=="in") {
temp.pop_back();//选取最靠后的in
temp.push_back((*i).second[j]);
}
}
for(int i=0; i<m; ++i) {
scanf("%s",time);
printf("%d\n",ans[gettime(time)]);
}
vector<pair<string,int>> r(ltime.begin(),ltime.end());//每辆车停车时间排序
sort(r.begin(),r.end(),cmp1);
cout<<r[0].first;
for(int i=1; i<r.size(); ++i)
if(r[i].second==r[i-1].second)
printf(" %s",r[i].first.c_str());
else break;
printf(" %02d:%02d:%02d\n",r[0].second/3600,r[0].second%3600/60,r[0].second%60);
return 0;
}