110404 Longest Nap


#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;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值