1095. Cars on Campus (30)

1.事件模拟

2.首先读取所有的汽车记录数据,筛选出合理的进入和离开时间,放到一个vector里面,对这个vector进行排序处理,进入时间早的放在前面

3.对每一秒进行模拟,已经进入的车辆用一个小根堆进行存储维护,离开时间早的,排在堆顶

3.取下一次进入校园车辆的时间,下一次离开校园车辆的时间,下一次查询的时间,取三者的最小值,直接跳那个时间点,进行处理,优化时间复杂度

4.一开始第4个例子超时,后来采用了第3点中提到的优化方法,结果还是超时,考虑到查询量较大,于是把查询的cout改为printf,就通过了。

Each input file contains one test case. Each case starts with two positive integers N (<= 10000), the number of records, and K (<= 80000) the number of queries. Then N lines follow, each gives a record in the format


1)最原始的一秒一秒进行模拟:



2)采用第3点的方法进行优化,还是超时



3)不进行时间事件模拟处理,仅输入数据,各测试点耗费时间:


4)最后把cout改为printf,通过:



AC源代码:

//#include<string>
//#include <iomanip>
#include<vector>
#include <algorithm>
//#include<stack>
#include<set>
#include<queue>
#include<map>
//#include<unordered_set>
#include<unordered_map>
//#include <sstream>
//#include "func.h"
//#include <list>
#include<stdio.h>
#include<iostream>
#include<string>
#include<memory.h>
#include<limits.h>
using namespace std;

struct CarNode{
	vector<pair<string, bool>> record;
	vector<pair<string, string>> validRecord;
	CarNode() :record(0), validRecord(0){};
};
struct RecordNode{

	string id, in, out;
	RecordNode() :id(""), in(""), out(""){};
	RecordNode(string i,string a,string b) :id(i), in(a), out(b){};

};
bool cmpRecord(const pair<string, bool>&a, const pair<string, bool>&b)
{
	return a.first < b.first;
}
bool cmpAllRecord(const RecordNode&a, const RecordNode&b)
{
	return a.in < b.in;
}
int char2int(char a)
{
	return a - '0';
}
int time2sec(string str)
{
	return (char2int(str[0]) * 10 + char2int(str[1])) * 60*60 + (char2int(str[3]) * 10 + char2int(str[4])) * 60 + char2int(str[6]) * 10 + char2int(str[7]);
}
struct cmp
{
	bool operator()(const RecordNode&a, const RecordNode&b)
	{
		return time2sec(a.out) > time2sec(b.out);
	}
};
bool cmpPark(const pair<string, int>&a, const pair<string, int>&b)
{
	if (a.second > b.second) return true;
	else if (a.second == b.second&&a.first < b.first) return true;
	else return false;
}
string sec2str(int a)
{
	int hour = a / 3600;
	int min = (a - hour * 3600) / 60;
	int sec = a - hour * 3600 - min * 60;

	char c1 = hour / 10 + '0';
	char c2 = hour % 10 + '0';
	string ans = "";
	ans += c1;
	ans += c2;
	ans += ":";
	c1 = min / 10 + '0';
	c2 = min % 10 + '0';
	ans += c1;
	ans += c2;
	ans += ":";
	c1 = sec / 10 + '0';
	c2 = sec % 10 + '0';
	ans += c1;
	ans += c2;
	return ans;

}
int main(void)
{
	int recordSum,querySum;
	cin >> recordSum >> querySum;

	map<string, CarNode> car;//建立car 哈希表
	for (int i = 0; i < recordSum; i++)
	{//输入记录
		string id, time, flag;
		cin >> id >> time >> flag;
		//0为进入,1为出去
		if (flag == "in")
			car[id].record.push_back({ time, 0 });
		else
			car[id].record.push_back({ time, 1 });
	}
	vector<RecordNode> allRecord(0);
	for (map<string, CarNode>::iterator ite = car.begin(); ite != car.end(); ite++)
	{//筛选出有效记录,统一发到allRecord容器中
		sort(ite->second.record.begin(), ite->second.record.end(), cmpRecord);
		for (int i = 0; i < ite->second.record.size() - 1; i++)
		{
			if (!ite->second.record[i].second && ite->second.record[i + 1].second)
			{//相邻的两条记录,第一条为进入,第二条为离开,则合理
				allRecord.push_back(RecordNode(ite->first, ite->second.record[i].first, ite->second.record[i + 1].first));
			}
		}
	}
	//根据进入时间,对有效记录进行排序
	sort(allRecord.begin(), allRecord.end(), cmpAllRecord);
	
	//输入查询记录
	vector<string> queryRecord(querySum);
	for (int i = 0; i < querySum; i++)
	{
		cin >> queryRecord[i];
	}
	sort(queryRecord.begin(), queryRecord.end());

	int parkCar = 0;
	int next = 0;
	int queryIdx = 0;
	map<string, int> parkTime;

	//优先队列,记录了在校园内的车,以离开时间大小建立小根堆
	priority_queue<RecordNode, vector<RecordNode>, cmp> inCampus;
	int maxTime = 0;
	string maxID = "";
	vector<pair<string, int>> maxTimeCar(0);
	for (int i = 0; i < 24 * 3600; i++)
	{
		while (next<allRecord.size() && time2sec(allRecord[next].in) == i)
		{//查看当前是否有车进入校园
			inCampus.push(allRecord[next]);
			next++;
			parkCar++;
		}
		while (!inCampus.empty() && time2sec(inCampus.top().out) == i)
		{//查看当前是否有车离开校园
			//记录停车时间
			parkTime[inCampus.top().id] += time2sec(inCampus.top().out) - time2sec(inCampus.top().in);

			if (parkTime[inCampus.top().id] >= maxTime)
			{
				maxTimeCar.push_back({ inCampus.top().id, parkTime[inCampus.top().id] });
				maxTime = parkTime[inCampus.top().id];
				maxID = inCampus.top().id;
			}

			inCampus.pop();
			parkCar--;
		}
		if (queryIdx<queryRecord.size() && time2sec(queryRecord[queryIdx]) == i)
		{
			queryIdx++;
			printf("%d\n",parkCar);//刚开始采用了cout输出,结果超时,改为printf后不超时
		}
		int inTime = 24 * 3600, outTime = 24 * 3600, queryTime = 24 * 3600;
		if (next < allRecord.size())//记录下一个需要处理的时间点
			inTime = time2sec(allRecord[next].in);
		if (!inCampus.empty())//记录下一个需要处理的时间点
			outTime = time2sec(inCampus.top().out);
		if (queryIdx < queryRecord.size())//记录下一个需要处理的时间点
			queryTime = time2sec(queryRecord[queryIdx]);

		int nextTime = min(min(inTime,outTime),queryTime);
		i = nextTime - 1;//因为for循环里面有i++,所以这里不需要直接达到nextTime

	}
	//对最大停车的车辆数组进行排序
	sort(maxTimeCar.begin(), maxTimeCar.end(), cmpPark);
	for (int i = 0; i < maxTimeCar.size(); i++)
	{
		if (maxTimeCar[i].second == maxTime)
		{//停车时间等于最大值,则输出
			cout << maxTimeCar[i].first << " ";//输出ID
		}
		else//不等,则直接跳出循环
			break;
	}
	cout << sec2str(maxTime) << endl;
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值