1. 程式人生 > >PAT 1026. Table Tennis

PAT 1026. Table Tennis

第一篇blog : p

測試點4考察的是"It is assumed that every pair of players can play for at most 2 hours."

測試點8則是"The waiting time must be rounded up to an integer minute(s)." 就是說,等待時間是通過四捨五入取整((waiting_time+30)/60)來計算的,而非向上取整(ceil).

有一點,覺得題目沒表述請的是,For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number.

當玩家佇列頭結點為VIP時,他將先從vip table中尋找可用的桌號最小的桌子來使用;而非首先從所有的桌子中,尋找桌號最小的桌子。

程式碼:

#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <deque>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

const int BEGIN = 28800, END = 75600;

struct Player
{
	int m_arrive_time;
	int m_playing_time;
	int m_serve_time;
	bool m_vip;
	bool m_serve;
	Player(int arrive_time, int playing_time, int vip): m_arrive_time(arrive_time), m_playing_time(playing_time),
		m_vip(vip), m_serve_time(END+1), m_serve(false) {}
};

inline bool arrive_time_cmp(const Player& a, const Player& b)
{
	return a.m_arrive_time < b.m_arrive_time;
}

inline bool serve_time_cmp(const Player& a, const Player& b)
{
	return a.m_serve_time < b.m_serve_time;
}

inline int get_time_from_str( char* s )
{
	return (10*(s[0]-'0')+s[1]-'0')*3600 + (10*(s[3]-'0')+s[4]-'0')*60 + 10*(s[6]-'0')+s[7]-'0';
}

inline void print_time_from_int( int t )
{
	printf("%d%d:%d%d:%d%d ",
		t/36000,
		t/3600%10,
		t/60%60/10,
		t/60%60%10,
		t%60/10,
		t%60%10);
}

deque<Player*> vip_player;
deque<Player> player;
vector<int> vip_table;
int n, k, m;
int time_now = BEGIN, player_now = 0;
int table_cnt[101], table_time[101];
bool table_tmp[101];

void init()
{
	char s[10];
	int play_time, vip, table_num;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i)
	{
		scanf("%s%d%d", s, &play_time, &vip);
		player.push_back(Player(get_time_from_str(s), play_time*60, vip ));
	}
	scanf("%d%d", &k, &m);
	memset(table_cnt, 0, sizeof(table_cnt));
	memset(table_time, 0, sizeof(table_time));
	memset(table_tmp, 0, sizeof(table_tmp));
	for (int i = 1; i <= m; ++ i)
	{
		scanf("%d", &table_num);	
		table_tmp[table_num] = true;
	}
	sort(table_tmp, table_tmp+m);
	for (int i = 1; i <= k; ++ i)
	{
		if (table_tmp[i] == true)
		{
			vip_table.push_back( i );
		}
	}
	sort( player.begin(), player.end(), arrive_time_cmp);
	for (auto it = player.begin(); it != player.end(); ++ it)
	{
		if (it->m_vip == true)
		{
			vip_player.push_back(&(*it));
		}
	}
}

int main()
{
	init();

	while(time_now < END)
	{
		if (player_now == n)
		{
			break;
		}

		// vip table
		for (auto it = vip_table.begin(); it != vip_table.end(); ++ it)
		{
			// 去掉已接受服務的vip
			while (vip_player.empty() == false 
				&& vip_player.front()->m_serve == true)
			{
				vip_player.pop_front();
			}

			if (vip_player.empty() == true
				|| vip_player.front()->m_arrive_time > time_now)
			{
				break;
			} else if (table_time[*it] <= 0)
			{

				table_time[*it] = vip_player.front()->m_playing_time<=7200? vip_player.front()->m_playing_time:7200;
				++ table_cnt[*it];
				vip_player.front()->m_serve = true;
				vip_player.front()->m_serve_time = time_now;
				vip_player.pop_front();
			}
		}

		// normal_table and remain_vip_table
		for (int i = 1; i <= k; ++ i)
		{
			if (table_time[i] <= 0)
			{
				while ( player_now < n
					&& player[player_now].m_serve == true)
				{
					++ player_now;
				}
				if (player_now == n
					|| player[player_now].m_arrive_time > time_now)
				{
					break;
				} else
				{
					table_time[i] = player[player_now].m_playing_time<=7200? player[player_now].m_playing_time: 7200;
					++ table_cnt[i];
					player[player_now].m_serve = true;
					player[player_now].m_serve_time = time_now;
				}
			}
		}

		for (int i = 1; i <= k; ++ i)
		{
			-- table_time[i];
		}

		++ time_now;
	}

	sort(player.begin(), player.end(), serve_time_cmp);
	for (auto it = player.begin(); it != player.end(); ++ it)
	{
		if ((*it).m_serve_time <= END)
		{
			print_time_from_int((*it).m_arrive_time);
			print_time_from_int((*it).m_serve_time);
//			printf("%f ", ((*it).m_serve_time-(*it).m_arrive_time)*1./60 );
			printf("%d\n", (30+(*it).m_serve_time-(*it).m_arrive_time)/60 );
		}
	}
	bool first = true;
	for (int i = 1; i <= k; ++ i)
	{
		if (first == true)
		{
			printf("%d", table_cnt[i]);
			first = false;
		} else
		{
			printf(" %d", table_cnt[i]);
		}
	}

	return 0;
}