1095. Cars on Campus (30)

1095. Cars on Campus (30)

时间限制
220 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

Zhejiang University has 6 campuses and a lot of gates. From each gate we can collect the in/out times and the plate numbers of the cars crossing the gate. Now with all the information available, you are supposed to tell, at any specific time point, the number of cars parking on campus, and at the end of the day find the cars that have parked for the longest time period.

Input Specification:

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

plate_number hh:mm:ss status

where plate_number is a string of 7 English capital letters or 1-digit numbers; hh:mm:ss represents the time point in a day by hour:minute:second, with the earliest time being 00:00:00 and the latest 23:59:59; and status is either in or out.

Note that all times will be within a single day. Each "in" record is paired with the chronologically next record for the same car provided it is an "out" record. Any "in" records that are not paired with an "out" record are ignored, as are "out" records not paired with an "in" record. It is guaranteed that at least one car is well paired in the input, and no car is both "in" and "out" at the same moment. Times are recorded using a 24-hour clock.

Then K lines of queries follow, each gives a time point in the format hh:mm:ss. Note: the queries are given in ascending order of the times.

Output Specification:

For each query, output in a line the total number of cars parking on campus. The last line of output is supposed to give the plate number of the car that has parked for the longest time period, and the corresponding time length. If such a car is not unique, then output all of their plate numbers in a line in alphabetical order, separated by a space.

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
     想一道新题目没想出来,那就来写一篇解题报告吧。这道题思路上并不难,主要就是繁琐。第一遍写的时候,我当场就蒙了,这个要多大的代码量啊,然后写了100多几十行的代码,细节之处晦涩无比,最后有一个测试点过不去,但是那段让人崩溃的代码我实在是不想去看了。第二次去写他已经是一个月后的事了,主要的区别是用熟了stl,好吧,我承认我是一个懒人。
     这道题目实际上是两道题目,一是统计每个时间校园内有多少辆车,而是找出在校园内呆的时间最久的车。谢天谢地这里的时间单位是秒,总长是一天,开一个int * sumcnt = int[24*60*60]的数组,一辆车子在A时间进入了,就在sumcnt[A]++,在A时间出去了,就在sumcnt[A]--,然后每个时间段校园内车子的数目实际上对应于这个数组的前缀和,因为数据一次性给出,所以用不着树状数组处理前缀和,将数组处理成前缀和就好了。
     第二个问题的话,因为懒,直接使用了map<string,int> 建立一个从车辆名称到他在学校的停留总时间的映射。每次发现一个合理的停留区间,就将这段时间间隔加在对应的名字,map中int会被初始化为0,所以可以直接加。然后呢,然后把代码写完就可以了。
     
# include <cstdio>
# include <algorithm>
# include <string>
# include <map>
# include <iostream>
# include <vector>
using namespace std;

const int debug = 0;
const int size = 10050;
const int range = 24*60*60;

int sumcnt[range];
string ToWatch(int time_point)
{
    char str[50];
    sprintf(str,"%02d:%02d:%02d",time_point/60/60,time_point%(60*60)/60,time_point%60);
    return string(str);
}
struct Log
{
    string name;
	int type;
    int time;
    void Print()
    {
	    cout << name << ' ' << ToWatch(time) << ' ' << type << endl;
	}
    bool match (const Log& cmper) const
      {
	    return name==cmper.name&&time<cmper.time&&type==0&&cmper.type==1;  
	  }
    bool operator < (const Log& cmper) const
      {
	    if (name!=cmper.name)
	        return name < cmper.name;
        else if (time != cmper.time)
            return time < cmper.time;
        else 
            return type <  cmper.type;
	  }
} car_log[size];
int ToDec(int hour,int min,int sec)
{
    return ( hour * 60 + min)*60 + sec;
}

typedef pair<int,int> time_range;
int main ()
{
	int i,j;
	int n,k;
    scanf("%d%d",&n,&k);
    string tmp;
    for (i=0;i<n;i++)
      {
        cin >> car_log[i].name;
		int hour,min,sec;
		scanf("%d:%d:%d",&hour,&min,&sec);
        car_log[i].time = ToDec(hour,min,sec);
        cin >> tmp;
		car_log[i].type = tmp == "out";
	  }
     sort(car_log,car_log+n);if (debug)for (i=0;i<n;i++) car_log[i].Print();
     map<string,int > index;
     int maxrange = -1;
     for (i=0;i<n;i++)
       {
	     if (i+1<n&&car_log[i].match(car_log[i+1]))
           {
			 index[car_log[i].name] += car_log[i+1].time - car_log[i].time;
			 if (index[car_log[i].name] > maxrange)    maxrange = index[car_log[i].name];
			 sumcnt[car_log[i].time]++,sumcnt[car_log[i+1].time]--;
	       }
	   }
     for (i=1;i<range;i++)
       sumcnt[i] += sumcnt[i-1]; 
     while (k--)
     {
	   int hour,min,sec;
	   scanf("%d:%d:%d",&hour,&min,&sec);
	   printf("%d\n",sumcnt[ToDec(hour,min,sec)]);
	 }
	 map<string,int>::iterator it;
	 for (it = index.begin();it!=index.end();it++)
	   if (it->second==maxrange)
	      cout << it->first << ' ';
	 cout << ToWatch(maxrange) << endl;   
     return 0; 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值