pat 1026. Table Tennis (30)

15 篇文章 0 订阅

https://www.patest.cn/contests/pat-a-practise/1026


根据http://blog.csdn.net/jtjy568805874/article/details/50809719 修改

#include <cstdio>
#include <algorithm>
using namespace std;
#define inthree(i,j,k) scanf("%d%d%d", &i,&j,&k)
#define rep(i,j,k) for(int i=j;i<=k;i++)
#define per(i,j,k) for(int i=k;i>=j;i--)
const int maxn = 1e4 + 10;
int n, t[maxn], x, y, z, m, u, f[maxn], vis[maxn], cnt[maxn];//t[] 每张桌子的可用时间 , f[] 每张桌子是不是vip, vis[] 每个顾客是否被服务, cnt[] 每张桌子服务了多少客人
struct cust {
	int x, y, f;
	bool friend operator < (struct cust a, struct cust b) {
		return a.x < b.x;
	}
}a[maxn];
void putout(int x)
{
	printf("%02d:%02d:%02d ", x / 3600, x / 60 % 60, x % 60);
}

void putmin(int x)
{
	printf("%d\n", x / 60 + (x % 60 < 30 ? 0 : 1));
}


int main()
{
	scanf("%d", &n);
	rep(i, 0, n - 1) 
	{
		scanf("%d:%d:%d", &x, &y, &z);
		a[i].x = x * 3600 + y * 60 + z;
		scanf("%d%d", &y, &a[i].f);
		a[i].y = min(y * 60, 7200);
	}
	sort(a, a + n);
	scanf("%d%d", &m, &u);
	while (u--){ scanf("%d", &x); f[x-1] = 1;}
	rep(i, 0, m - 1) t[i] = 8 * 3600;
	rep(i, 0, n - 1)
	{
		if (vis[i]) continue;
		int now = 0;//最早可用的桌子
		rep(j, 0, m - 1) if (t[now] > t[j]) now = j;
		if (max(t[now], a[i].x) >= 21 * 3600) break;//超出营业时间
		if (t[now] <= a[i].x) //不用排队
		{
			int vip = -1;//如果当前用户是vip,则用vip桌中最小的
			per(j, 0, m - 1)
			{
				if (t[j] <= a[i].x) now = j;
				if (t[j] <= a[i].x&&f[j]) vip = j;
			}
			if (a[i].f && vip != -1) now = vip;
			cnt[now]++;
			putout(a[i].x); putout(a[i].x);
			printf("0\n"); t[now] = a[i].x + a[i].y;
		}
		else //要排队 
		{
			int vip = -1; //如果vip桌子同时可用
			per(j, 0, m - 1) if (t[j] == t[now] && f[j]) vip = j;
			if (vip != -1) //先处理vip桌子
			{
				int flag = 0; // 队列里是否有vip
				for (int j = i; j < n&&a[j].x <= t[vip]; j++)
				{
					if (a[j].f&&!vis[j])
					{
						vis[j] = 1;
						putout(a[j].x); putout(t[vip]);
						putmin(t[vip] - a[j].x);
						t[vip] += a[j].y;
						flag = 1; break;
					}
				}
				if (flag) { cnt[vip]++; i--; continue; }
			}

			cnt[now]++;//如果没有vip桌子同时可用,now是普通桌子, 给第一个人用
			putout(a[i].x); putout(t[now]);
			putmin(t[now]-a[i].x);
			t[now] += a[i].y;
		}
	}
	rep(i, 0, m - 1) printf("%d%s", cnt[i], i == m - 1 ? "\n" : " ");
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值