题意:
给出n个车牌号、时间点、进出状态的记录,然后查询k个时间点这时校园内的车辆个数。最后还要输出在校园里面呆的时间最长的车的车牌号,以及呆了多久的时间。如果有多辆车就按照它的字母从小到大输出车牌。
配对要求是,如果一个车多次进入未出,取最后一个值;如果一个车多次out未进入,取第一个值。
注意:一个车可能出入校园好多次,停车的时间应该取之和。
思路:
这个模拟题还蛮难的,主要是不符合要求的情况不好处理。我是做半天没搞出来,看了网上的代码写的,主要思路如下:
in用flag=1表示,out用flag=-1表示。一开始先按车牌排序,再按时间排序,这样保持同一辆车的情况拍在一起,这样就能把合法的车辆选出来放入新数组。之后再把新数组按照时间排序。
为了避免超时,所以先把i时刻前的所有车辆数cnt[i]算出来,cnt[i]=cnt[i-1]+flag[i]。又因为查询的时间是按照升序拍的,所以可以用一个index记录上一次查询到的位置,下次从index查询即可。
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<string>
#include<map>
#include<vector>
using namespace std;
const int maxn = 10500;
struct node {string name;int time;int h, m, s;int flag;
}car[maxn];
int n, k;
map<string, int> carlast;
vector<node> res;
int maxtime;
int cnt[maxn];bool cmp1(node a, node b) {if (a.name != b.name) {return a.name < b.name;} else {return a.time < b.time;}
}bool cmp2(node a, node b) {return a.time < b.time;
}int main() {scanf("%d%d", &n, &k);for (int i = 0; i < n; i++) {cin >> car[i].name;scanf("%d:%d:%d", &car[i].h, &car[i].m, &car[i].s);car[i].time = car[i].h * 3600 + car[i].m * 60 + car[i].s;string status;cin >> status;if (status == "in") {car[i].flag = 1;} else if (status == "out") {car[i].flag=-1; } }sort(car, car + n, cmp1);for (int i = 0; i < n-1; i++) {if (car[i].name==car[i+1].name&&car[i].flag == 1 && car[i + 1].flag == -1 && car[i].time<car[i + 1].time) {res.push_back(car[i]);res.push_back(car[i + 1]);carlast[car[i].name] += (car[i + 1].time - car[i].time);if (maxtime < carlast[car[i].name]) {maxtime = carlast[car[i].name];}}}sort(res.begin(), res.end(), cmp2);for (int i = 0; i < res.size(); i++) {if (i == 0) {cnt[i] = res[i].flag;} else {cnt[i] = cnt[i - 1] + res[i].flag;}}int h, m, s, time;int index=0;while (k--) {scanf("%d:%d:%d", &h, &m, &s);time = h * 3600 + m * 60 + s;int j;for (j = index; j < res.size(); j++) {if (time < res[j].time) {printf("%d\n", cnt[j - 1]);break;} else if (j==res.size()-1) { //比所有时间都晚printf("%d\n", cnt[j]);}}index = j;}for (auto i = carlast.begin(); i != carlast.end();i++) {if (i->second == maxtime) {cout << i->first << " ";}}printf("%02d:%02d:%02d\n", maxtime / 3600, (maxtime % 3600) / 60, maxtime % 60);return 0;
}