PAT 1095. Cars on Campus

#include<iostream>
#include<algorithm>
#include<vector>
#include<cstdio>
#include<cstring>
using namespace std;
/*
	算法分为三个过程
		1.选出有效记录:
			根据id号和时间排序,之后遍历并判断记录是否有效
		2.查询某一时刻的停车数:
			对有效的记录按时间排序后,如果对其遍历,遇到in停车数就加1,遇到out停车数就减1。
			并且要查询的时间也是递增的,这样遍历一次记录就能查询出结果。
		3.查询最大停车时间:
			遍历第一条中的排序结果,查询停车时间最长的。若某辆车一天中多次进出,停车时间累加
*/
struct record{
	char id[8];
	int time;
	int status;
	int valid;
}r[10010],t[10010];
bool cmp(record a,record b){
	if(strcmp(a.id,b.id)!=0) return strcmp(a.id,b.id)<0;
	else return a.time<b.time;
}
bool cmpt(record a,record b){
	return a.time<b.time;
}
void pritime(int s){
	printf("%.2d:%.2d:%.2d",s/60/60,s/60%60,s%60);
}
int main(){
	int n,num_query;
	cin>>n>>num_query;
	int h,m,s;
	char status[10];
	for (int i = 0; i < n; i++){//输入
		scanf("%s %d:%d:%d %s",&r[i].id,&h,&m,&s,&status);
		r[i].time=h*60*60+m*60+s;
		if(strcmp(status,"in")==0) r[i].status=1;
		else r[i].status=0;
		r[i].valid=0;
	}
	sort(r,r+n,cmp);//根据每个车的id号和时间排序,为了筛选出有效对象
	int index=0;
	for (int i = 0; i < n; i++){//转存
		if(strcmp(r[i].id,r[i+1].id)==0&&r[i].status==1&&r[i+1].status==0){
			r[i].valid=1;
			t[index++]=r[i];
			t[index++]=r[i+1];
			i++;
		}
	}
	sort(t,t+index,cmpt);//把清洗后的数组再按时间排序,则遍历时,遇到in停车数加1,遇到out停车数-1
	int num_park=0,step=0;
	for (int i = 0; i < num_query; i++){//查询某个时刻的停车数
		scanf("%d:%d:%d",&h,&m,&s);
		int second=h*60*60+m*60+s;
		while(t[step].time<=second&&step<index){
			if(t[step].status==1)
				num_park++;
			else if(t[step].status==0)
				num_park--;
			step++;
		}
		cout<<num_park<<endl;
	}
	char *pre="";//输出最长停车时间
	vector<char *> v;
	int parktime=0,max=0;
	for (int i = 0; i < n; i++)
	{
		if(r[i].valid){
			if(strcmp(r[i].id,pre)!=0){//若更换了id
				if(parktime>max){//判断上一个id的parktime是否最大
					v.clear();
					v.push_back(pre);
					max=parktime;
				}else if(parktime==max)
					v.push_back(pre);
				parktime=0;//当前id的parktime置0
				pre=r[i].id;
			}
			parktime+=r[i+1].time-r[i].time;//当前id的停车时间累加
		}
	}
	if(parktime>max){//判断最后一个id的parktime是否最大
		v.clear();
		v.push_back(pre);
		max=parktime;
	}else if(parktime==max)
		v.push_back(pre);
	for (int i = 0; i < v.size(); i++)
		cout<<v[i]<<" ";
	pritime(max);
	return 0;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值