数据结构之Cars on Campus问题

前言

在最近整理大学前两年学的内容时,突然发现了这个数据结构程序,主要目标是实时观测一个校园停车场的状态。现发布在这里,希望可以给学习的同袍们一点帮助。

题目要求

8-1 Cars on Campus

Zhejiang University has 8 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:
数据结构之Cars on Campus问题
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

具体代码

#include <cstdio>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
using namespace std;
typedef struct info* INFO;  //INFO is a struct pointer which points to a struct storing information about cars
struct info
{
    vector<int> in;     //vector in contains  time the car came in
    vector<int> out;    //vector in contains  time the car went out
    int total_time;     //total_time calculates the total time the car parked in the canpus
};
map<string, INFO> Map;  //Map connect the plate number and corresponding struct pointer INFO
vector<int> query;      //query stores the time of queries (transfer the time to seconds so it's INT)
int n, K;               //n is the total number of records and K is the number of queries
//this function process the input
void ReadData()
{
    cin >> n >> K;
    string s1, s2;   //s1 and s2 are just temporary strings
    int hour, minute, second;
    for (int i = 0; i < n; i++)
    {
        cin >> s1;
        //if there is no such car information, then construct its struct info
        if (!Map.count(s1))
        {
            INFO temp = new struct info();
            Map[s1] = temp;
        }
        //read the time string and transfer it to hour,minute and second
        cin >> s2;
        hour = (s2[0] - '0') * 10 + (s2[1] - '0');  minute = (s2[3] - '0') * 10 + (s2[4] - '0');    second = (s2[6] - '0') * 10 + (s2[7] - '0');
        cin >> s2;
        //if it's in time then push it to the vector in and transfer the time to seconds at the same time
        if (s2 == "in") (Map[s1]->in).push_back(hour * 3600 + minute * 60 + second);
        else if (s2 == "out")   (Map[s1]->out).push_back(hour * 3600 + minute * 60 + second);
        //if it's out time then push it to the vector out and transfer the time to seconds at the same time
    }
    //read the queries
    //transfer the time to seconds and store them
    for (int i = 0; i < K; i++)
    {
        cin >> s2;
        hour = (s2[0] - '0') * 10 + (s2[1] - '0');  minute = (s2[3] - '0') * 10 + (s2[4] - '0');    second = (s2[6] - '0') * 10 + (s2[7] - '0');
        query.push_back(hour * 3600 + minute * 60 + second);
    }
}
//this function delete invalid time and pair the in time and out time
void Delete_Invalid_Time()
{
    map<string, INFO> ::iterator it = Map.begin(); //define an iterator to go through the map
    vector<int> temp_in, temp_out;  //these are temporary vectors to avoid delete particular element in vector which is slow
    while (it != Map.end())
    {
        sort((it->second->in).begin(), (it->second->in).end()); //sort the in time vector
        sort((it->second->out).begin(), (it->second->out).end());   //sort the out time vector
        vector<int> ::iterator it_in, it_out; //define an iterator to go through the vector
        it_in = (it->second->in).begin();   it_out = (it->second->out).begin();
        temp_in.clear();    //clear temp_in to remove elements stored last loop
        temp_out.clear();   //clear temp_out to remove elements stored last loop
        while (it_in != (it->second->in).end() && it_out != (it->second->out).end())
        {
            while (*it_in > * it_out&& it_out != (it->second->out).end())   it_out++; //while out time is less than current in time, out time is invalid
            if (it_out == (it->second->out).end()) break; //no out time is valid now
            while (it_in < (it->second->in).end() - 1 && *(it_in + 1) <= *it_out)    it_in++; //if the next time is nearer to the current out time then the next time is valid
            //now *it_in and *it_out are paired valid in and out time
            temp_in.push_back(*it_in);  temp_out.push_back(*it_out);    it_in++;    it_out++;
        }
        it->second->in = temp_in;   //refresh the vector in
        it->second->out = temp_out; //refresh the vector out
        it++;
    }
}
//this function consider the state of every car at particular time
//so calculate the number of cars at particular time
//also calculate total times a particular car park in campus
void Decide_State_And_Time()
{
    vector<int> ans1(K, 0); //ans1 stores the number of cars corresponding queries
    map<string, INFO> ::iterator it = Map.begin();//define an iterator to go through the map
    while (it != Map.end())
    {
        int query_pointer = 0;  //query_pointer is the index of vector query
        it->second->total_time = 0; //initialize total time of a car
        for (int i = 0; i < it->second->in.size(); i++) it->second->total_time += (it->second->out)[i] - (it->second->in)[i];//calculate total time of a car
        for (int i = 0; i < it->second->in.size(); i++) //decide if the car was in campus at every query time
        {
            while (it->second->in[i] > query[query_pointer] && query_pointer < K) query_pointer++;
            if (query_pointer == K) break;
            while (it->second->out[i] > query[query_pointer] && query_pointer < K) //this condition is true when the car is in campus at this time
            {
                ans1[query_pointer]++;
                query_pointer++;
            }
        }
        it++;
    }
    for (int i = 0; i < K; i++)    cout << ans1[i] << '\n'; //print out the answer of queries
}
//this function defines the rules of alphabetical order when sorting
bool compare(string s1,string s2)
{
	string :: iterator it1 = s1.begin(), it2 = s2.begin(); //initialize the iterator
	while(*it1 == *it2)	//ignore the same part
	{
		it1++;	it2++;
	} 
	if(isalpha(*it1) && isdigit(*it2))	return true;	//letters are before digits
	else if(isalpha(*it2) && isdigit(*it1)) return false; //letters are before digits
	else if(isdigit(*it1) && isdigit(*it2))
	{
		if(*it1 > *it2) return false;	//small digit is before large digit
		else return true;
	}else
	{
		if(toupper(*it1) < toupper(*it2)) return true;		//Aa should be in front of Bb
		else if(toupper(*it1) > toupper(*it2)) return false;
		else if(*it1 < *it2) return true;	//big letter is before small letter
		else return false;
	}
}
//this function calculate the maximal parking time and print out the cars
void Generate_Maxtime()
{
    vector<string> ans2;    //ans stores the cars parking with maximal time
    int Max = 0; //initialize maximal time of parking
    map<string, INFO> ::iterator it = Map.begin();//define an iterator to go through the map
    while (it != Map.end()) //calculate maximal parking time
    {
        if (it->second->total_time > Max) Max = it->second->total_time;
        it++;
    }
    it = Map.begin();
    while (it != Map.end()) //put the target cars in ans2
    {
        if (it->second->total_time == Max) ans2.push_back(it->first);
        it++;
    }
    sort(ans2.begin(), ans2.end(),compare); //sort ans2 in alphabetical order
    for (int i = 0; i < ans2.size(); i++)    cout << ans2[i] << ' '; //print out the plate numbers of targets
    //transfer the maximal time to hour, minute and second
    int max_hour, max_minute, max_second;
    max_second = Max % 60;  Max = Max / 60; max_minute = Max % 60;  Max = Max / 60; max_hour = Max;
    printf("%02d:%02d:%02d\n", max_hour, max_minute, max_second); //print out maximal parking time
}
int main()
{
    ReadData(); //process input
    Delete_Invalid_Time();//delete invalid time and pair the in time and out time
    Decide_State_And_Time();//calculate the number of cars at particular time and also calculate total times a particular car park in campus
    Generate_Maxtime();//calculate the maximal parking time and print out the cars
}

后记

这是Data Structure课程的最后一个大程。只要厘清各函数间关系后也不算很难。至此DS课程的大程已全部整理完毕。之后我将陆续整理ADS课程的各大程一并放上来,以望共勉

上一篇:福建十三水用例图


下一篇:阅读任务2