- 用结构体保存每条记录的信息
- 用从00:00:00开始到当前逝去的秒数来衡量时间的先后
- 对所有记录进行排序
- 用vector数组保存每辆车的有效记录
- 对每辆车的停车时长进行计算,同时记录停得最久的车
- 通过队列对校园内车数进行统计
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<unordered_map>
#include<queue>
using namespace std;
int recordNum, queryNum;
int id = 0;
unordered_map<string, int> plate2id;
int getId(string plate) {
if (plate2id.count(plate) == 0) {
plate2id[plate] = id++;
}
return plate2id[plate];
}
struct node1 {
string plate;
int hour, minute, second, time, status;
}record[10000];
vector<node1> temp[5000];
queue<node1> valid[5000]; //每辆车的有效记录
struct node2 {
int hour, minute, second, time;
}query[80000];
int getTime(int hour, int minute, int second) {
return hour * 3600 + minute * 60 + second;
}
bool cmp1(node1 n1, node1 n2) {
if (n1.plate != n2.plate)
return n1.plate < n2.plate;
else return n1.time < n2.time;
}
int main() {
scanf("%d %d", &recordNum, &queryNum);
for (int i = 0;i < recordNum;i++) {
cin >> record[i].plate;
scanf("%d:%d:%d", &record[i].hour, &record[i].minute, &record[i].second);
record[i].time = getTime(record[i].hour, record[i].minute, record[i].second);
string temp;
cin >> temp;
cin.get();
record[i].status = temp == "in" ? 1 : 0;
}
for (int i = 0;i < queryNum;i++) {
scanf("%d:%d:%d", &query[i].hour, &query[i].minute, &query[i].second);
query[i].time = getTime(query[i].hour, query[i].minute, query[i].second);
}
sort(record, record + recordNum, cmp1);
for (int i = 0;i < recordNum;i++) {
int id = getId(record[i].plate);
if (record[i].status == 1) {
if (!temp[id].empty() && temp[id].back().status == 1) { //上一条也为in,上一条记录无效
temp[id].pop_back();
}
temp[id].push_back(record[i]);
}
else {
if (!temp[id].empty() && temp[id].back().status == 1) { //上一条记录为in,这条记录有效
temp[id].push_back(record[i]);
}
}
}
int index = 0, maxTime = 0;
unordered_map<string, int> total; //记录每辆车停的时长
vector<string> maxTimeCar;
for (int i = 0;i < id;i++) {
if (temp[i].size() > 1) { //存在有效记录
string plate = temp[i][0].plate;
for (int j = 1;j < temp[i].size();j += 2) { //计算停车时长
total[plate] += temp[i][j].time - temp[i][j - 1].time;
}
if (total[plate] > maxTime) {
maxTimeCar.clear();
maxTimeCar.push_back(plate);
maxTime = total[plate];
}
else if (total[plate] == maxTime) {
maxTimeCar.push_back(plate);
}
for (int j = 1;j < temp[i].size();j += 2) { //将有效记录放入队列
valid[index].push(temp[i][j - 1]);
valid[index].push(temp[i][j]);
}
index++;
}
}
int carCount = 0;
for (int i = 0;i < queryNum;i++) {
for (int j = 0;j < index;j++) {
while (!valid[j].empty() && valid[j].front().time <= query[i].time) {
if (valid[j].front().status == 1) {
carCount++;
}
else carCount--;
valid[j].pop();
}
}
printf("%d\n", carCount);
}
for (int i = 0;i < maxTimeCar.size();i++) {
cout << maxTimeCar[i] << " ";
}
int maxHour, maxMinute, maxSecond;
maxHour = maxTime / 3600;
maxMinute = (maxTime - maxHour * 3600) / 60;
maxSecond = maxTime % 60;
printf("%02d:%02d:%02d", maxHour, maxMinute, maxSecond);
}
二刷:
用一个数组record
存下所有记录,然后根据车牌号对记录进行分类,根据规则挑选出有效的记录,剔除无效的记录。之后用一个unordered_set
来标识哪些是有效的记录,方便在遍历原数组record
时判断有效性。因为给出的查询在时间上是有序的,同时遍历车辆进出记录record
和查询query
即可。
另:foreach遍历的是容器的深拷贝,如果要进行修改,加上&。
#include<iostream>
#include<string>
#include<unordered_map>
#include<unordered_set>
#include<algorithm>
#include<vector>
using namespace std;
int numRecord, numQuery;
const int IN = 1, OUT = 0;
struct Record {
int id; //id is used to identify valid record
string plate;
int hour, minute, second, time, status;
}record[10010];
struct Query {
int hour, minute, second, time;
}query[100000];
int getTime(int hour, int minute, int second) {
return hour * 3600 + minute * 60 + second;
}
bool cmp(Record &a, Record &b) {
return a.time < b.time;
}
unordered_set<int> validRecord;
bool isValid(Record &r) {
return validRecord.count(r.id) != 0;
}
int main() {
cin >> numRecord >> numQuery;
for (int i = 0; i < numRecord; i++) {
record[i].id = i;
cin >> record[i].plate;
scanf("%d:%d:%d", &record[i].hour, &record[i].minute, &record[i].second);
string s;
cin >> s;
record[i].status = s == "in" ? IN: OUT;
record[i].time = getTime(record[i].hour, record[i].minute, record[i].second);
}
for (int i = 0; i < numQuery; i++) {
scanf("%d:%d:%d", &query[i].hour, &query[i].minute, &query[i].second);
query[i].time = getTime(query[i].hour, query[i].minute, query[i].second);
}
sort(record, record + numRecord, cmp);
unordered_map<string, int> totalTime; //total park time for each car
unordered_map<string, vector<Record> > car; //devide records by its plate
for (int i = 0; i < numRecord; i++) {
string plate = record[i].plate;
if (record[i].status == OUT) {
//if last record of this car is not IN, dump this
if (car[plate].empty() || car[plate].back().status != IN) {
continue;
}
}
else if (record[i].status == IN) {
if (!car[plate].empty() && car[plate].back().status == IN) {
car[record[i].plate].pop_back();
}
}
car[plate].push_back(record[i]);
}
for (auto &it : car) {
if (it.second.size() % 2 != 0) {
it.second.pop_back();
}
}
//record valid records
for (auto it : car) {
for (auto e : it.second) {
validRecord.insert(e.id);
}
}
//calculate total park time
for (auto it : car) {
vector<Record> &tmp = it.second;
if (tmp.empty())
continue;
int total = 0;
for (int i = 0; i < tmp.size(); i += 2) {
total += tmp[i + 1].time - tmp[i].time;
}
totalTime[it.first] = total;
}
//calculate number of cars on campus
int carCount = 0, index = 0;
for (int i = 0; i < numQuery; i++) {
while (record[index].time <= query[i].time && index < numRecord) {
if (isValid(record[index])) {
if (record[index].status == IN) {
++carCount;
}
else --carCount;
}
++index;
}
printf("%d\n", carCount);
}
//find maximum park time car(s)
int maxParkTime = 0;
vector<string> plates;
for (auto it : totalTime) {
if (it.second > maxParkTime) {
maxParkTime = it.second;
plates.clear();
plates.push_back(it.first);
}
else if (it.second == maxParkTime) {
plates.push_back(it.first);
}
}
sort(plates.begin(), plates.end());
for (string s : plates) {
cout << s << " ";
}
printf("%02d:%02d:%02d", maxParkTime / 3600, maxParkTime / 60 - maxParkTime / 3600 * 60, maxParkTime % 60);
}