1095 Cars on Campus (30分)

14 篇文章 0 订阅

在这里插入图片描述
在这里插入图片描述

  • 用结构体保存每条记录的信息
  • 用从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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值