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


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值