A1026 Table Tennis (30 分)

本文介绍了一个高尔夫俱乐部管理系统的设计与实现,该系统使用C++语言,通过结构体和向量来存储和管理高尔夫球员的信息,包括到达时间、开始打球时间、打球时长以及是否为贵宾。系统还考虑了贵宾和非贵宾球员的优先级,以及特定球桌的服务时间。通过对球员信息的分类和排序,实现了高效的时间管理和资源分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
const int K = 110;
const int INF = 1e9;
struct player
{
	int arrival, start, train;
	bool isvip;
}newplayer;
struct table
{
	int endtime, servenum;
	bool isvip;
}tab[K];
vector<player>v;
int change(int h, int m, int s) { return h * 3600 + m * 60 + s; }
bool cmp1(player a, player b) { return a.arrival < b.arrival; }
bool cmp2(player a, player b) { return a.start < b.start; }
int nextvip(int vip)
{
	vip++;
	while (vip < v.size() && v[vip].isvip == 0) { vip++; }
	return vip;
}
void allocate(int idx, int id)
{
	v[id].start = max(tab[idx].endtime, v[id].arrival);
	tab[idx].endtime = v[id].start + v[id].train;
	tab[idx].servenum++;
}
int main()
{
	int n, k, m,viptab;
	scanf("%d", &n);
	int sttime = change(8, 0, 0);
	int edtime = change(21, 0, 0);
	for (int i = 0; i < n; i++)
	{
		int h, m, s, train, isvip;
		scanf("%d:%d:%d %d %d", &h, &m, &s, &train, &isvip);
		newplayer.arrival = change(h, m, s);
		newplayer.start = edtime;//初始化为21点
		if (newplayer.arrival >= edtime) continue;
		newplayer.train = train <= 120 ? train*60 : 7200;
		newplayer.isvip = isvip;
		v.push_back(newplayer);
	}
	scanf("%d%d", &k, &m);
	for (int i = 1; i <= k; i++) { tab[i].endtime = sttime; tab[i].servenum = tab[i].isvip = 0; }
	for (int i = 0; i < m; i++) { scanf("%d", &viptab); tab[viptab].isvip = 1; }
	sort(v.begin(), v.end(), cmp1);
	int i = 0, vipi = -1;
	vipi = nextvip(vipi);//vipi指向当前队列的第一个vip
	while (i < v.size())
	{
		int idx, minend = INF;//最早空闲桌号和时间
		for (int j = 1; j <= k; j++)
		{
			if (tab[j].endtime < minend)
			{
				minend = tab[j].endtime;
				idx = j;
			}
		}
		if (tab[idx].endtime >= edtime) break;//最早空闲的结束时间长于营业时间,直接break
		if (v[i].isvip == 1 && i < vipi)
		{
			i++;
			continue;
		}
		//按照球桌球员分类
		if (tab[idx].isvip == 1)//vip球桌
		{
			if (v[i].isvip == 1)//vip球员
			{
				allocate(idx, i);
				vipi = nextvip(vipi);
				i++;
			}
			else//非vip球员
			{
				if (vipi<v.size()&&v[vipi].arrival <= tab[idx].endtime)//存在vip在等,注意控制vipi要小于size
				{
					allocate(idx, vipi);
					vipi = nextvip(vipi);
				}
				else//不存在vip在等
				{
					allocate(idx, i);
					i++;
				}
			}
		}
		else//不是vip球桌,这里要注意一点:如果存在多台空闲球桌,vip球员会优先选择空闲的VIP球桌而不是普通球桌
		{
			if (v[i].isvip == 0)
			{
				allocate(idx, i);
				i++;
			}
			else//球员是vip
			{
				int mintime=INF,vipidx=-1;
				for (int j = 1; j <= k; j++)
				{
					if (tab[j].isvip == 1 && tab[j].endtime < mintime)
					{
						mintime = tab[j].endtime;
						vipidx = j;
					}
				}
				if (v[i].arrival >= tab[vipidx].endtime&&vipidx != -1)
				{
					allocate(vipidx, i);
					vipi = nextvip(vipi);
					i++;
				}
				else
				{
					allocate(idx, i);
					vipi = nextvip(vipi);
					i++;
				}
			}
		}
	}
	sort(v.begin(), v.end(), cmp2);
	for (int i = 0; i < v.size() && v[i].start < edtime; i++)
	{
		int t1 = v[i].arrival;
		int t2 = v[i].start;
		printf("%02d:%02d:%02d ", t1 / 3600, t1 % 3600 / 60, t1 % 60);
		printf("%02d:%02d:%02d ", t2 / 3600, t2 % 3600 / 60, t2 % 60);
		printf("%.0f\n", round((t2 - t1) / 60.0));
	}
	for (int i = 1; i <= k; i++)
	{
		printf("%d", tab[i].servenum);
		if (i < k)printf(" ");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值