PAT 1026 Table Tennis (30分)

蛮复杂的一道模拟题
需要注意的点挺多的:
1.优先级问题(vip桌子的安排)
2.playtime规定在2h之内,超过2h按2h计算
3.servingtime等于或大于21点的不输出

#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include <string>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <string.h>
#include <map>
#include <set>

using namespace std;
int N, Pt,h,m,s,tag, K, M, ind,pi,vi;

typedef struct player
{
	int atime;
	int ptime;
	int stime;
	int wtime;
};
player P[10010];
player V[10010];

typedef struct table {
	int index;
	int stime;
	int players;
	int tag;
};
table T[110];

bool cmp1(player a,player b)
{
	return a.atime < b.atime;
}

bool cmp2(player a, player b)
{
	return a.stime < b.stime;
}

bool cmp3(table a, table b)
{
	if(a.stime != b.stime)return a.stime<b.stime;
	else return a.index < b.index;
}

bool cmp4(table a, table b)
{
	return a.index < b.index;
}


vector <int> vip_table;


int main()
{
#ifdef  LIU
	FILE *ss;
	freopen_s(&ss, "1.txt", "r", stdin);
#endif 
	cin >> N;
	int open = 8 * 3600;
	int close = 21 * 3600;
	char c;
	vi = 0; pi = 0;
	for (int i = 0; i < N; i++)
	{
		cin >> h >> c >> m >> c >> s;
		cin >> Pt>>tag;
		if (tag == 1)
		{
			V[vi].atime= h * 3600 + m * 60 + s;
			V[vi].ptime = min(120*60,Pt*60);
			vi++;
		}
		else {
			P[pi].atime= h * 3600 + m * 60 + s;
			P[pi].ptime = min(120*60,Pt*60);
			pi++;
		}

	}
	sort(P, P + pi, cmp1);//按player到达时间排序
	sort(V, V + vi, cmp1);

	cin >> K >> M;
	for (int i = 0; i < K; i++)
	{
		if (i < M) {
			cin >> ind;
			T[ind - 1].tag = 1;//数组中编号为0-K-1
			vip_table.push_back(ind-1);
		}
		T[i].index = i + 1;
		T[i].players = 0;
		T[i].stime = open;
	}
	sort(vip_table.begin(), vip_table.end());

	//安排前K个顾客中的vip若N<K,则安排前N个
	int posv = 0,posp=0;
	int otable = 0;
	int vtable = 0;
    for (int t = 0; t < K; t++)
	{
		if (posv + posp == N)break;
		if (posv < vi&&(posp==pi||V[posv].atime < P[posp].atime))
		{//是vip先检测有无空闲的vip桌子
			if(vtable<M){
				V[posv].stime = V[posv].atime;
				V[posv].wtime = 0;
				T[vip_table[vtable]].stime = V[posv].stime + V[posv].ptime; 
				if (V[posv].stime < close) {
					T[vip_table[vtable]].players++;
				}
				vtable++;
			}
			else {
				while (T[otable].tag==1) {
					++otable;
				}
				V[posv].stime = V[posv].atime;
				V[posv].wtime = 0;
				T[otable].stime = V[posv].stime + V[posv].ptime;
				if (V[posv].stime < close) {
					T[otable].players++;
				}
				otable++;
			}
			posv++;

		}
		else if (posp < pi)
		{
			while(T[otable].tag == 1&& (vtable==M||otable < vip_table[vtable]))otable++;
			if (T[otable].tag == 1) vtable++;

				P[posp].stime = P[posp].atime;
				P[posp].wtime = 0;
				T[otable].stime = P[posp].stime + P[posp].ptime;
				if (P[posp].stime < close) {
					T[otable].players++;
				}
		    otable++;
			posp++;
		}

	}
	
	
	   
		while (posp + posv < N)//顾客没有安排完
		{
			sort(T, T + K, cmp3);
			if (T[0].tag == 1&&posv<vi && V[posv].atime <= T[0].stime)//是vip桌子
			{//看队列中有没有vip
				V[posv].stime = T[0].stime;
				V[posv].wtime = (V[posv].stime - V[posv].atime+30) / 60;
				if (V[posv].stime < close) {
					T[0].stime += V[posv].ptime;
					T[0].players++;
				}
				posv++;
			}
			else
			{//给顺次下一位顾客安排桌子
				if (posp<pi&&(posv==vi||P[posp].atime < V[posv].atime))
				{  //一般顾客
					P[posp].stime = max(P[posp].atime,T[0].stime);
					P[posp].wtime = (P[posp].stime-P[posp].atime+30)/60;
					T[0].stime = P[posp].stime + P[posp].ptime;
					if (P[posp].stime < close) {
						T[0].players++;
					}
					posp++;
				}
				else
				{
					
					V[posv].stime = max(V[posv].atime,T[0].stime);
					V[posv].wtime = (V[posv].stime - V[posv].atime+30) / 60;
					T[0].stime = V[posv].stime + V[posv].ptime;
					if (V[posv].stime < close) {
						T[0].players++;
					}
					posv++;
				}
			}
		}

		sort(P, P + pi, cmp2);//按player服务时间排序
		sort(V, V + vi, cmp2);
		posp = posv = 0;
		while (posp+posv<N)
		{
			if (posp<pi&&(posv == vi || P[posp].stime < V[posv].stime))
			{
				if (P[posp].stime < close) {
					printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",
						P[posp].atime / 3600, (P[posp].atime % 3600) / 60, P[posp].atime % 60,
						P[posp].stime / 3600, (P[posp].stime % 3600) / 60, P[posp].stime % 60,
						P[posp].wtime);
				}
				++posp;
			}
			else {
				if (V[posv].stime < close) {
					printf("%02d:%02d:%02d %02d:%02d:%02d %d\n",
						V[posv].atime / 3600, (V[posv].atime % 3600) / 60, V[posv].atime % 60,
						V[posv].stime / 3600, (V[posv].stime % 3600) / 60, V[posv].stime % 60,
						V[posv].wtime);
				}
				++posv;

			}			
		}

		sort(T, T + K, cmp4);
		for (int t = 0; t < K; t++)
		{  
			if (t == 0) cout << T[t].players;
			else cout << ' ' << T[t].players;
		}
		cout << endl;
		
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值