#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;
#define TIME_UNIT 60
static const int START_TIME = 10 * TIME_UNIT;
static const int END_TIME = 18 * TIME_UNIT;
class Interval
{
public:
void Init(int startTime, int endTime)
{
m_startTime = startTime;
m_endTime = endTime;
}
class DurationComparer
{
public:
bool operator()(const Interval& a, const Interval& b)
{
int durationA = a.GetDuration();
int durationB = b.GetDuration();
if (durationA > durationB)
return true;
else if (durationA < durationB)
return false;
else
return (a.m_startTime < b.m_startTime);
}
};
class NormalComparer
{
public:
bool operator()(const Interval& a, const Interval& b)
{
return (a.m_startTime > b.m_startTime);
}
};
int GetDuration() const
{
return m_endTime - m_startTime;
}
void Display()
{
int startHour = GetHour(m_startTime);
int startMinute = GetMinute(m_startTime);
char buf[3];
GetMinuteStr(startMinute, buf);
int duration = GetDuration();
int durationHour = GetHour(duration);
int durationMinute = GetMinute(duration);
cout << "nap starts at " << startHour << ':' << buf << " and will last for ";
if (durationHour > 0)
cout << durationHour << " hours and ";
cout << durationMinute << " minutes.";
}
private:
static int GetHour(int x)
{
return x / TIME_UNIT;
}
static int GetMinute(int x)
{
return x % TIME_UNIT;
}
static void GetMinuteStr(int x, char* buf)
{
if (x < 10)
sprintf(buf, "0%d", x);
else
sprintf(buf, "%d", x);
}
public:
int m_startTime;
int m_endTime;
};
template <typename T>
static void Swap(T* data, int index1, int index2)
{
T temp = *(data + index1);
*(data + index1) = *(data + index2);
*(data + index2) = temp;
}
template <typename T, typename GreaterThanFunc>
static int Partition(T* data, int left, int right, GreaterThanFunc greaterThanFunc)
{
T& ref = *(data + right);
int lastSmallerThanRefIndex = left - 1;
for (int i = left; i < right; ++i)
{
if (greaterThanFunc(ref, *(data + i)))
{
++lastSmallerThanRefIndex;
Swap(data, lastSmallerThanRefIndex, i);
}
}
++lastSmallerThanRefIndex;
Swap(data, lastSmallerThanRefIndex, right);
return lastSmallerThanRefIndex;
}
template <typename T, typename GreaterThanFunc>
static void QuickSort(T* data, int left, int right, GreaterThanFunc greaterThanFunc)
{
if (left >= right)
return;
if ((right - left) == 1)
{
if (greaterThanFunc(*(data + left), *(data + right)))
Swap(data, left, right);
return;
}
int mid = Partition(data, left, right, greaterThanFunc);
QuickSort(data, left, mid - 1, greaterThanFunc);
QuickSort(data, mid + 1, right, greaterThanFunc);
}
static void OutputLongestNap(Interval* intervals, int cnt)
{
QuickSort(intervals, 0, cnt - 1, Interval::DurationComparer());
cout << "the longest ";
intervals[cnt - 1].Display();
cout << endl;
}
static int GetTimeNo(char*& buf)
{
int number = 0;
while(((*buf) >= '0') && ((*buf) <= '9'))
{
number = number * 10 + (*buf) - '0';
++buf;
}
return number;
}
static void GetStartTimeAndEndTimeFromLine(char* buf, int& startTime, int& endTime)
{
int i = 0;
int hour = GetTimeNo(buf);
++buf;
int minute = GetTimeNo(buf);
++buf;
startTime = hour * TIME_UNIT + minute;
hour = GetTimeNo(buf);
++buf;
minute = GetTimeNo(buf);
++buf;
endTime = hour * TIME_UNIT + minute;
}
#define MAX_BUF 4096
static char s_buf[MAX_BUF];
static void RunTestCase(int cnt)
{
Interval* intervals = new Interval[cnt];
Interval* durations = new Interval[cnt + 1];
int startTime, endTime;
for (int i = 0; i < cnt; ++i)
{
fgets(s_buf, MAX_BUF, stdin);
GetStartTimeAndEndTimeFromLine(s_buf, startTime, endTime);
intervals[i].Init(startTime, endTime);
}
QuickSort(intervals, 0, cnt - 1, Interval::NormalComparer());
durations[0].Init(START_TIME, intervals[0].m_startTime);
int lastEndTime = START_TIME;
for (int i = 1; i < cnt; ++i)
{
durations[i].Init(intervals[i-1].m_endTime, intervals[i].m_startTime);
}
durations[cnt].Init(intervals[cnt - 1].m_endTime, END_TIME);
OutputLongestNap(durations, cnt + 1);
delete[] intervals;
delete[] durations;
}
static void Test()
{
int len;
int i = 1;
while(fgets(s_buf, MAX_BUF, stdin))
{
if ((s_buf[0] == '\0') || (s_buf[0] == '\n'))
return;
len = strlen(s_buf);
if (s_buf[len - 1] == '\n')
s_buf[len - 1] = '\0';
cout << "Day #" << i << ": ";
RunTestCase(atoi(s_buf));
++i;
}
}
int main(int argc, char* argv[])
{
Test();
return 0;
}