给出n个汽车的出入记录,给出k个询问,每次询问时间,求该时间点停车场的停车数量。最后输出停车总时长最长的车,输出车牌,如果有多辆就按字母顺序输出结果,最后输出总时长。出入记录要有in和out成对出现才有效,一辆车连续多次in,取最后一次,连续多次out,取第一次。
这一题,用map将字符串名称与数组下标对应起来,将时间转化为数字,先把所有记录排序,再将对应的有效记录分配给不同的车子,根据每辆车的当前出入情况判断:
1、当前为in,如果所有记录中当前为in,则删除车子中的这一条记录,将最新记录加入。
(导致可能存在只有一条in记录的情况)
2、当前为out,如果所有记录中当前为in,则将新记录加入。(导致可能存在最后一条是in的情况)
一开始是每次询问就遍历一遍,一提交发现第五个测试点超时了,后来改用一个数组记录每一秒停车场的车数,每次询问直接给出结果,提交后,第五个测试点错误,弄了很久才发现,是没有完全排除无效数据,可能存在in后就没有out,遍历车子出入记录时,将数量大小为奇数的减一或者将最后一条记录删除。
有一种做法比较好 ,将所有有效数据放到一个数组中,将每一条记录的停车数计算出来,这样可以不用直接开八万多的数组记录每一秒的车辆,可以减少开销,不过要遍历比较才可以找到想要的结果,计算最长时间就感觉麻烦一点了。
(用时:2:26:53.51)
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<cstdlib>
//#include <bits/stdc++.h>
using namespace std;
struct Records {
int plateNumber;
int time;
int status;
};
bool cmp(Records a,Records b)
{
return a.time < b.time;
}
int main()
{
int n,k;
scanf("%d%d",&n,&k);
string pNumber;
char statusStr[4];
int hour,minute,second;
map<string,int> numToIndex;
map<int,string> indexToNum;
int length = 0;
int index = 0;
vector<Records> recordsVec;
for(int i=0; i<n; i++) {
cin>>pNumber;
scanf("%d:%d:%d %s",&hour,&minute,&second,statusStr);
if(numToIndex.count(pNumber)==0) {
index = length;
numToIndex[pNumber] =length;
indexToNum[length] = pNumber;
length++;
}
index = numToIndex[pNumber];
Records record;
record.plateNumber = index;
record.time=hour*60*60+minute*60+second;
switch(statusStr[0]) {
case 'i':
record.status = 1;
break;
case 'o':
record.status = 0;
break;
default:
break;
}
recordsVec.push_back(record);
}
sort(recordsVec.begin(),recordsVec.end(),cmp);
vector<Records> carRecords[length];
Records r;
int s;
for(int i=0; i<recordsVec.size(); i++) {
//第一条记录一定是in
if(carRecords[recordsVec[i].plateNumber].size()==0) {
if(recordsVec[i].status==1) {
carRecords[recordsVec[i].plateNumber].push_back(recordsVec[i]);
}
} else {
s = carRecords[recordsVec[i].plateNumber].size();
r = carRecords[recordsVec[i].plateNumber][s-1];
//车辆当前的记录是in
if(r.status==1) {
//又是in,相同,删除原来的in记录
if(recordsVec[i].status==1) {
carRecords[recordsVec[i].plateNumber].erase(carRecords[recordsVec[i].plateNumber].begin()+s-1);
}
carRecords[recordsVec[i].plateNumber].push_back(recordsVec[i]);
} else { //车辆当前的记录是out
//是in,加入
if(recordsVec[i].status==1) {
carRecords[recordsVec[i].plateNumber].push_back(recordsVec[i]);
}
}
}
}
int time = 0;
int carNum = 0;
int carNumFt[86401]= {0};
for(int i=0; i<length; i++) {
s = carRecords[i].size();
if(s%2==1) {
//数量大小是奇数,删除最后一条记录
carRecords[i].pop_back();
s--;
}
for(int j=0; j<s; j++) {
switch(carRecords[i][j].status) {
case 1:
//有in 相应时间点的车辆数+1
carNumFt[carRecords[i][j].time]++;
break;
case 0:
carNumFt[carRecords[i][j].time]--;
break;
default:
break;
}
}
}
for(int i=1; i<86401; i++) {
carNumFt[i] += carNumFt[i-1];
}
for(int t=0; t<k; t++) {
scanf("%d:%d:%d",&hour,&minute,&second);
carNum = 0;
time = hour * 60 *60 + minute * 60 + second;
printf("%d\n",carNumFt[time]);
}
int cost[length] = {0};
for(int i=0; i<length; i++) {
s = carRecords[i].size();
for(int j=0; j<s; j+=2) {
cost[i] += carRecords[i][j+1].time - carRecords[i][j].time;
}
}
int maxNum = cost[0];
for(int i=1; i<length; i++) {
if(maxNum < cost[i]) {
maxNum =cost[i];
}
}
vector<string> longestTimeCar;
for(int i=0; i<length; i++) {
if(maxNum == cost[i]) {
longestTimeCar.push_back(indexToNum[i]);
}
}
sort(longestTimeCar.begin(),longestTimeCar.end());
for(int i=0; i<longestTimeCar.size(); i++) {
if(i==0) {
cout<<longestTimeCar[i];
} else {
cout<<" "<<longestTimeCar[i];
}
}
hour = maxNum/(60*60);
minute = maxNum %(60*60) /60;
second = maxNum %60;
printf(" %02d:%02d:%02d\n",hour,minute,second);
return 0;
}