PAT A1095 Cars on Campus
Sample Input:
16 7
JH007BD 18:00:01 in
ZD00001 11:30:08 out
DB8888A 13:00:00 out
ZA3Q625 23:59:50 out
ZA133CH 10:23:00 in
ZD00001 04:09:59 in
JH007BD 05:09:59 in
ZA3Q625 11:42:01 out
JH007BD 05:10:33 in
ZA3Q625 06:30:50 in
JH007BD 12:23:42 out
ZA3Q625 23:55:00 in
JH007BD 12:24:23 out
ZA133CH 17:11:22 out
JH007BD 18:07:01 out
DB8888A 06:30:50 in
05:10:00
06:30:50
11:00:00
12:23:42
14:00:00
18:00:00
23:59:00
Sample Output:
1
4
5
2
1
0
1
JH007BD ZD00001 07:20:09
-
思路 1:
先按车牌排序(同车牌按时间先后排序),排序后从头到尾遍历,筛选出有效数据(同一辆车:前一记录in,后out) valid[ ],筛选的过程中,将同一辆车停留时长累加到map中,使车牌和时长对应
再将valid[ ]按时间先后排序
对每一输入查询时刻,从头开始遍历,找出这一时刻前的所有记录,对in计数器cnt++,out计数器cnt–;
再通过对map的遍历,得到当天最大停留时长,即对应的车s -
code 1:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string>
#include <map>
using namespace std;
int n, k;
map<string, int> mp; //存储每辆车对应的停留时间 -> 求最大停留时间
struct Car{
string pNum;
int h, m, s, time; //time:进/出发生的时刻(以s为单位)
bool flag; //true=in false=out
}cars[10010], valid[10010];
bool cmp1(Car a, Car b){
if(a.pNum != b.pNum) return a.pNum < b.pNum;
else return a.time < b.time;
}
bool cmp2(Car a, Car b){
return a.time < b.time;
}
int tTos(int h, int m, int s){
//把格式化时间hh:mm:ss 转化为以s为单位的整数
int t = h * 3600 + m * 60 + s;
return t;
}
void sTot(int s){
//格式化输出
int h = s/3600;
int m = s%3600/60;
int ss = s - h*3600 - m*60;
printf("%02d:%02d:%02d", h, m, ss);
}
int main(){
scanf("%d %d", &n, &k);
string f;
for(int i = 0; i < n; ++i){
cin >> cars[i].pNum;
scanf("%d:%d:%d", &cars[i].h, &cars[i].m, &cars[i].s);
cin >> f;
if(f == "in") cars[i].flag = true;
else cars[i].flag = false;
cars[i].time = tTos(cars[i].h, cars[i].m, cars[i].s);
}
sort(cars, cars+n, cmp1);
//1.筛选出有效数据
int idex = 0;
for(int i = 1; i < n; ++i){
if(cars[i].pNum == cars[i-1].pNum){
if(cars[i].flag == false && cars[i-1].flag == true){
valid[idex] = cars[i-1];
valid[++idex] = cars[i];
mp[cars[i].pNum] += cars[i].time - cars[i-1].time;
idex++;
}
}
}
sort(valid, valid+idex, cmp2);
//查找输入时刻还在学校的车数:遍历输入时刻之前的所有记录 in:cnt++ | out:cnt--;
int cnt, qH, qM, qS;
for(int i = 0; i < k; ++i){
scanf("%d:%d:%d", &qH, &qM, &qS);
int tt = tTos(qH, qM, qS);
cnt = 0;
for(int j = 0; j < idex; ++j){
if(valid[j].time <= tt){
if(valid[j].flag == true) cnt++;
else cnt--;
}else break;
}
printf("%d\n", cnt);
}
//先遍历一遍map找最大值,再遍历一次把和最大值相等的车牌输出
int Max = 0;
for(auto it = mp.begin(); it != mp.end(); ++it){
if(it->second > Max){
Max = it->second;
}
}
for(auto it = mp.begin(); it != mp.end(); ++it){
if(it->second == Max){
cout << it->first << " ";
}
}
sTot(Max);
return 0;
}
-
思路 2:
求最大值操作可以放到,处理原始数据的循环里(即筛选有效数据的循环),在筛选的过程中不断更新Max -
code 2: 部分
int inTime = cars[i].time - cars[i-1].time;
if(mp.count(cars[i].pNum) == 0){
mp[cars[i].pNum] = 0; //map中没有这个车牌 置0
}
mp[cars[i].pNum] += inTime; //累加该车总停留时长
maxTime = max(maxTime, mp[cars[i].pNum]); //更新全局maxTime
-
思路2:双指针法+打表法
对有效数据的处理,类似于 Phone Bills ,用双指针分组遍历
对查询部分,采用预处理,求出每一秒的状态(从0遍历到243600+6060+60 = 90060,q[i] += q[i-1]
)存到q[]中,直接将查询时间hh:mm:ss转换成秒t,输出q[t]即可 -
T2 code :
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int q[maxn]; //打表:用于记录,每一秒学校内的车数
struct Record{
string plate;
int h, m, s, time, status;
}re[maxn];
struct Car{
string plate;
int park;
}car[maxn];
bool cmp(Record a, Record b){
return a.plate != b.plate ? a.plate < b.plate : a.time < b.time;
}
int main(){
int nr, nq;
scanf("%d %d", &nr, &nq);
for(int i = 0; i < nr; ++i){
cin >> re[i].plate;
scanf("%d:%d:%d", &re[i].h, &re[i].m,& re[i].s);
string ss; cin >> ss; if(ss[0] == 'o') re[i].status = 1; //0 == in , 1 == out
re[i].time = re[i].h * 3600 + re[i].m * 60 + re[i].s;
}
sort(re, re+nr, cmp);
int i = 0, j = 1, idex = 0, max_time = 0;
memset(q, 0, sizeof(q));
while(j < nr){
while(re[j].plate == re[i].plate) j++;
int k = i;
while(k + 1 < j){
if(re[k].status == 0 && re[k+1].status == 1){
car[idex].plate = re[i].plate;
int in_time = re[k].time, out_time = re[k+1].time;
int d = out_time - in_time;
q[in_time]++; q[out_time]--;
car[idex].park += d;
max_time = max(max_time, car[idex].park); //找出最大停留时长
k += 2;
}else k++;
}
idex++;
i = j++;
}
//求出每一秒学校内的车数:打表
for(int i = 1; i < maxn; ++i){
q[i] += q[i-1];
}
for(int i = 0; i < nq; ++i){
int qh, qm, qs;
scanf("%d:%d:%d", &qh, &qm, &qs);
int qt = qh * 3600 + qm * 60 + qs;
printf("%d\n", q[qt]);
}
for(int i = 0; i < idex; ++i){
if(car[i].park == max_time) cout << car[i].plate << " ";
}
printf("%02d:%02d:%02d", max_time / 3600, max_time / 60 % 60, max_time % 60);
return 0;
}
- T3 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10010;
int time_table[100010], max_parktime = 0;
map<string, int> park_time;
struct Record
{
string plate;
int time, status;
}record[maxn];
int GetTime(int h, int m, int s) { return h * 3600 + m * 60 + s; }
bool cmp(Record a, Record b) { return a.plate != b.plate ? a.plate < b.plate : a.time < b.time; }
void DealRecord(int n)
{
int left = 0, right = 1;
while(left < n)
{
while(right < n && record[right].plate == record[left].plate) right++;
for(int i = left+1; i < right; ++i)
{
if(record[i].status == -1 && record[i-1].status == 1)
{
int in = record[i-1].time, out = record[i].time;
park_time[record[i].plate] += (out - in);
time_table[in]++; time_table[out]--;
max_parktime = max(park_time[record[i].plate], max_parktime);
}
}
left = right++;
}
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for(int i = 0; i < n; ++i)
{
int th, tm, ts;
string tsign;
cin >> record[i].plate;
scanf("%d:%d:%d", &th, &tm, &ts);
cin >> tsign;
record[i].time = GetTime(th, tm, ts);
record[i].status = tsign[0] == 'i' ? 1 : -1;
}
sort(record, record + n, cmp);
DealRecord(n);
int last_time = -1, last_num = 0; //WRONG:样例 1, 5 :注意:last_time要从-1开始,因为有可能查询00:00:00
for(int i = 0; i < m; ++i)
{
int qh, qm, qs;
scanf("%d:%d:%d", &qh, &qm, &qs);
int qt = GetTime(qh, qm, qs);
for(int j = last_time+1; j <= qt; ++j)
{
if(time_table[j] != 0) last_num += time_table[j];
}
printf("%d\n", last_num);
last_time = qt;
}
for(auto it = park_time.begin(); it != park_time.end(); ++it)
{
if(it->second == max_parktime) cout << it->first << " ";
}
printf("%02d:%02d:%02d", max_parktime / 3600, max_parktime / 60 % 60, max_parktime % 60);
return 0;
}
- T4 code:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 24 * 60 * 60;
int status[maxn];
struct record
{
int _time;
bool _sign; // 1 in , 0 out;
};
unordered_map<string, vector<record> > mp;
bool cmp(record & a, record & b)
{
if(a._time != b._time)
{
return a._time < b._time;
}else
{
return a._sign > b._sign;
}
}
int GetTime(int h, int m, int s)
{
return h * 60 * 60 + m * 60 + s;
}
void PrintTime(int t)
{
printf("%02d:%02d:%02d", t / 60 / 60 , t / 60 % 60 , t % 60);
}
int Max = 0;
set<string> winner;
void GetLongest(string plate, vector<record> & ans)
{
int sum = 0;
for(int i = 1; i < ans.size(); ++i)
{
if(ans[i]._sign == false && ans[i-1]._sign == true)
{
int in = ans[i-1]._time, out = ans[i]._time;
status[in]++;
status[out]--;
sum += out - in;
}
}
if(sum > Max)
{
Max = sum;
winner.clear();
winner.insert(plate);
}else if(sum == Max)
{
winner.insert(plate);
}
}
int main()
{
int n, nq;
scanf("%d %d", &n, &nq);
for(int i = 0; i < n; ++i)
{
string tplate, tsign;
int th[3];
cin >> tplate;
scanf("%d:%d:%d", &th[0], &th[1], &th[2]);
cin >> tsign;
int ttime = GetTime(th[0], th[1], th[2]);
mp[tplate].push_back(record{ttime, tsign[0] == 'i' ? true : false});
}
for(auto it = mp.begin(); it != mp.end(); ++it)
{
sort(it->second.begin(), it->second.end(), cmp);
GetLongest(it->first, it->second);
}
int num = 0, pre = 0, now;
for(int i = 0; i < nq; ++i)
{
int th, tm, ts;
scanf("%d:%d:%d", &th, &tm, &ts);
now = GetTime(th, tm, ts);
for(int j = pre; j <= now; ++j)
{
if(status[j])
{
num += status[j];
}
}
printf("%d\n", num);
pre = now+1;
}
for(auto it : winner) cout << it << " ";
PrintTime(Max);
return 0;
}