1095 Cars on Campus

练习 专栏收录该内容
322 篇文章 0 订阅

题目

题意: 给出n个车牌号、时间点、进出状态的记录,然后查询k个时间点这时校园内的车辆个数。最后还要输出在校园里面呆的时间最长的车的车牌号,以及呆了多久的时间。如果有多辆车就按照它的字母从小到大输出车牌。
配对要求是,如果一个车多次进入未出,取最后一个值;如果一个车多次out未进入,取第一个值。
注意:一个车可能出入校园好多次,停车的时间应该取之和。

tip:map+排序+状态记录

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
using namespace std;
struct ss {
	string time;
	string state;
};
bool cmp(struct ss a,struct ss b) {
	return a.time<b.time;
}
bool cmp1(pair<string,int>a,pair<string ,int>b) {
	if(a.second==b.second)
		return a.first<b.first;
	else return a.second>b.second;
}
int gettime(string time) {
	return stoi(time.substr(0,2))*3600+stoi(time.substr(3,2))*60+stoi(time.substr(6,2));
}
int main() {
	int n,m;
	scanf("%d %d\n",&n,&m);
	map<string ,int> ltime;
	map<string,vector<struct ss>>s;
	char name[100],time[30],state[10];
	for(int i=0; i<n; ++i) {
		scanf("%s %s %s\n",name,time,state);
		s[name].push_back({time,state});//按照车牌号将所有记录一并打包先 
	}
	int ans[86403]= {0};//记录每时刻的停车车辆 
	for(auto i=s.begin(); i!=s.end(); ++i) {
		sort((*i).second.begin(),(*i).second.end(),cmp);//每辆车记录时间排序 
		vector<struct ss> temp;
		int t=0;
		ltime[(*i).first]=0;
		while(t<(*i).second.size()&&(*i).second[t].state=="in")//选择最晚的 in 
			t++;
		if(t)
			t--;
		if(t<(*i).second.size())
			temp.push_back((*i).second[t]);//暂时存在 in,与下一个out配对 
		ltime[(*i).first]=0;
		for(int j=t+1; j<(*i).second.size(); ++j)
			if(temp.size()&&(*i).second[j].state!=temp[0].state&&(*i).second[j].time!=temp[0].time) {
				if(temp[0].state=="in") {//状态转换时,由in到out 
					int a=gettime(temp[0].time);
					int b=gettime((*i).second[j].time);
					ltime[(*i).first]+=b-a;//记录停车时间 
					for(int k=a; k<b; ++k)
						ans[k]++;//停车区间++ 
				}
				temp.pop_back();
				temp.push_back((*i).second[j]);//交换状态 
			} else if(temp[0].state=="in") {
				temp.pop_back();//选取最靠后的in 
				temp.push_back((*i).second[j]);
			}
	}
	for(int i=0; i<m; ++i) {
		scanf("%s",time);
		printf("%d\n",ans[gettime(time)]);
	}
	vector<pair<string,int>> r(ltime.begin(),ltime.end());//每辆车停车时间排序 
	sort(r.begin(),r.end(),cmp1);
	cout<<r[0].first;
	for(int i=1; i<r.size(); ++i)
		if(r[i].second==r[i-1].second)
			printf(" %s",r[i].first.c_str());
		else break;
	printf(" %02d:%02d:%02d\n",r[0].second/3600,r[0].second%3600/60,r[0].second%60);
	return 0;
}

 

  • 1
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:马嘣嘣 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值