PAT1095 Cars on Campus (30)(模拟)

10 篇文章 0 订阅

题意:

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

注意:一个车可能出入校园好多次,停车的时间应该取之和。

思路:

这个模拟题还蛮难的,主要是不符合要求的情况不好处理。我是做半天没搞出来,看了网上的代码写的,主要思路如下:

in用flag=1表示,out用flag=-1表示。一开始先按车牌排序,再按时间排序,这样保持同一辆车的情况拍在一起,这样就能把合法的车辆选出来放入新数组。之后再把新数组按照时间排序。

为了避免超时,所以先把i时刻前的所有车辆数cnt[i]算出来,cnt[i]=cnt[i-1]+flag[i]。又因为查询的时间是按照升序拍的,所以可以用一个index记录上一次查询到的位置,下次从index查询即可。

#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<string>
#include<map>
#include<vector>
using namespace std;
const int maxn = 10500;
struct node {
	string name;
	int time;
	int h, m, s;
	int flag;
}car[maxn];
int n, k;
map<string, int> carlast;
vector<node> res;
int maxtime;
int cnt[maxn];
	
bool cmp1(node a, node b) {
	if (a.name != b.name) {
		return a.name < b.name;
	} else {
		return a.time < b.time;
	}
}

bool cmp2(node a, node b) {
	return a.time < b.time;
}

int main() {
	scanf("%d%d", &n, &k);
	for (int i = 0; i < n; i++) {
		cin >> car[i].name;
		scanf("%d:%d:%d", &car[i].h, &car[i].m, &car[i].s);
		car[i].time = car[i].h * 3600 + car[i].m * 60 + car[i].s;
		string status;
		cin >> status;
		if (status == "in") {
			car[i].flag = 1;
		} else if (status == "out") {
			car[i].flag=-1;	
		}	
	}
	sort(car, car + n, cmp1);
	for (int i = 0; i < n-1; i++) {
		if (car[i].name==car[i+1].name&&car[i].flag == 1 && car[i + 1].flag == -1 && car[i].time<car[i + 1].time) {
			res.push_back(car[i]);
			res.push_back(car[i + 1]);
			carlast[car[i].name] += (car[i + 1].time - car[i].time);
			if (maxtime < carlast[car[i].name]) {
				maxtime = carlast[car[i].name];
			}
		}
	}
	sort(res.begin(), res.end(), cmp2);
	for (int i = 0; i < res.size(); i++) {
		if (i == 0) {
			cnt[i] = res[i].flag;
		} else {
			cnt[i] = cnt[i - 1] + res[i].flag;
		}
	}
	int h, m, s, time;
	int index=0;
	while (k--) {
		scanf("%d:%d:%d", &h, &m, &s);
		time = h * 3600 + m * 60 + s;
		int j;
		for (j = index; j < res.size(); j++) {
			if (time < res[j].time) {
				printf("%d\n", cnt[j - 1]);
				break;
			} else if (j==res.size()-1) {	//比所有时间都晚
				printf("%d\n", cnt[j]);
			}
		}
		index = j;
	}
	for (auto i = carlast.begin(); i != carlast.end();i++) {
		if (i->second == maxtime) {
			cout << i->first << " ";
		}
	}
	printf("%02d:%02d:%02d\n", maxtime / 3600, (maxtime % 3600) / 60, maxtime % 60);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值