1026 Table Tennis (仅26分)

本文介绍了一个游戏厅模拟算法,该算法使用优先队列管理游戏桌的使用情况,考虑到普通玩家和VIP玩家的不同需求,确保了游戏桌的有效分配。通过四舍五入处理游戏时间,避免了向上取整带来的资源浪费。

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

1. 起止时间8.00-21.00之间

2.vip优先用vip空闲桌最小编号 ,不是所有空闲桌子

3. 使用时间不超过120*60秒

4.四舍五入 即round  不是向上取整ceil

//代码只有26,刚开始只有21 ,改为四舍五入以后22  后来认为是在空闲桌子存在时那那一刻  也存在排队的, 即排队的时候 有几个的结束时间恰好相等,后来推翻了这个观点 看了别人的坑点  发现vip优先使用vip空闲桌子,不是编号最小的桌子,改了也只有26  

1和2的测试点过不去

在空闲的桌子使用那注释了两端代码  都是修改时留下的  第一段仅考虑了空闲时刻没有排队的

第二段则是考虑了排队的  但依然没有改善

while段则是vip与vip桌子的对应

 

 

/*
思路:把所有的排一队   有优先级的在单独排一队
桌子:(优先队列) 所有可用桌子排一队 有优先级的排一队

优先级排一队主要是为了vip使用时的操作
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<cmath>

using namespace std;

const int ST = 8*60*60;
const int ET = 21*60*60;
int pre = ST;
struct P {
	int gettime;
	int pt;
	int p;
	P() {
		gettime = ET;
		pt = 0;
	}

	friend bool operator <(const P& a, const P& b) {
		return a.gettime > b.gettime;
	}
};
struct Table {
	int gt, st, cnt, et;//到达  服务  第几个桌子  结束时长
	int vip; 
	Table() {
		gt = ST;
		st = ST;
		et = ST;
		cnt = 0;
		vip = 0;
	}
	friend bool operator <(const Table& a, const Table& b) {
		if(a.et == b.et){
			return a.vip < b.vip;
		}
		return a.et > b.et;
	}
};
struct IDX {
	int i;
	int et;
	IDX() {
		et = ST;
	}
	friend bool operator <(const IDX& a, const IDX& b) {
		if(a.et == b.et)
			return a.i > b.i;
		return a.et > b.et;
	}
};
priority_queue<P> q, p;
priority_queue<IDX > ans, ansp;
priority_queue<Table> a;

int main() {

	int n, k, m;
	cin >> n;

	for(int i=0; i<n; i++) {
		int h, m, s, pt;
		P tmp;

		scanf("%d:%d:%d %d %d", &h, &m, &s, &pt, &tmp.p);
		tmp.gettime = h*3600+m*60+s;
		if(tmp.gettime>ET) continue;
		if(pt > 120) {
			tmp.pt = 120*60;
		} else tmp.pt = pt*60;

		if(tmp.p == 1) {
			p.push(tmp);
		}
		q.push(tmp);
	}
	scanf("%d%d", &k, &m);
	int flag[k];
	int Sum[k];

	for(int i=0; i<k; i++) {
		Table tmp;
		tmp.cnt = i;
		//a.push(tmp);
		IDX t1;
		t1.i = i;
		ans.push(t1);
	}

	memset(flag, 0, sizeof(flag));
	memset(Sum, 0, sizeof(Sum));

	for(int i=0; i<m; i++) {
		IDX t1;

		cin >> t1.i;
		t1.i -=1;
		ansp.push(t1);
		flag[t1.i] = 1;
	}

	int j = 0;
	int all = 0;
	while(!q.empty()) {
		P tmp = q.top(), tmpq;

		Table tt;

		if(!p.empty()) {//>=
			tmpq = p.top();
			if(tmp.p && tmp.gettime < tmpq.gettime) {//默认不会有相同时间到达的
				q.pop();//都是vip  不同则说明  有vip tmp用了特区
				continue;//从头开始
			} else if(tmp.gettime > tmpq.gettime) {
				p.pop();
				continue;
			}
		}else{
			if(tmp.p == 1){
				q.pop();
				continue;
			}
		}

		//	cout << endl  << a.size() << endl << endl << endl;

		while(!a.empty()) {
			IDX t1;

			tt = a.top();
			while(tt.et <= tmp.gettime) {//可以在下一个之前释放的,就让他释放
				t1.et = tt.et;
				t1.i = tt.cnt;

				if(flag[tt.cnt]) {
					ansp.push(t1);
				}
				ans.push(t1);
				a.pop();
				if(a.empty()) break;
				tt = a.top();
			}
			break;
		}
		IDX idx;
		/*	if(!ans.empty()) {//有空闲桌子
						idx = ans.top();
						if(flag[idx]) {
							ansp.pop();
						}
						ans.pop();

						tt.gt = tt.st = tmp.gettime;
						if(tt.st < ST) {
							tt.st = ST;
						}

						tt.et = tt.st+tmp.pt;
						tt.cnt = idx;
						q.pop();
						if(tt.st >= ET && tt.et > ET) {
							break;
						}else if(tt.et > ET){
							tt.et = ET;
						}
						Sum[tt.cnt]++;
						//	printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
						printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));

					}*/
		bool flagt = false;
		while(!ans.empty()) {//有空闲桌子
			idx = ans.top();
			if(flag[idx.i]) {//都是优先级  排整齐 
				if(!ansp.empty()) {
					IDX t2 = ansp.top();

					if(t2.i == idx.i) {
						;
					} else if(t2.i > idx.i) {

						ans.pop();
						continue;
					} else if(t2.i < idx.i) {
						ansp.pop();
						continue;
					}
				}
				else {//在ansp找不到 说明之前ansp pop过   
					ans.pop();
					continue;
				}
			}
			tt.gt = tt.st = tmp.gettime;
			tt.cnt = idx.i;

			if(!ansp.empty() && tmp.gettime == tmpq.gettime) {//是vip  并有vip桌子
				tt.cnt = ansp.top().i;
				tt.vip = 1;
				ansp.pop();
			} else ans.pop();

			if(tt.st < ST) {
				tt.st = ST;
			}
			tt.et = tt.st+tmp.pt;

			q.pop();
			if(tt.st >= ET) {
				break;
			} else if(tt.et > ET) {
				tt.et = ET;
			}
			flagt = true;
			Sum[tt.cnt]++;
			//		cout << tt.cnt<< "============";
			//	printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
			printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
			break;
		}
		/*
		if(!ans.empty()) {//有空闲桌子  可能之前堵得
		IDX idx = ans.top();

		if(flag[idx.i] && idx.et >= tmpq.gettime) { //VIP桌  且之前有等待的vip
			//VIP上
			ansp.pop();
			p.pop();
			tt.gt = tmpq.gettime;
			tt.st = idx.et;
			tt.et = tt.st+tmpq.pt;
		} else if(idx.et >= tmp.gettime) {//之前有等待的普通||vip
			q.pop();
			tt.gt = tmp.gettime;
			tt.st = idx.et;
			tt.et = tt.st+tmp.pt;
		} else {//空闲一会才来的玩家
			q.pop();
			tt.gt = tt.st = tmp.gettime;
			tt.et = tt.st+tmp.pt;
		}
		if(tt.st >= ET && tt.et>ET) {//ET之前未开始
			break;
		} else if(tt.et > ET) {
			tt.et = ET;
		}

		ans.pop();

		if(tt.st < ST) {
			tt.st = ST;
		}
		tt.cnt = idx.i;
		if(tt.st >= ET && tt.et > ET) {
			break;
		} else if(tt.et > ET) {
			tt.et = ET;
		}
		Sum[tt.cnt]++;
		//	printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
		printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
		} */
		if(!flagt) { //需等待
			a.pop();
			if(flag[tt.cnt] && tt.et >= tmpq.gettime) { //等待一会的有优先级 并且有有vip到了
				//VIP上
				p.pop();
				tt.gt = tmpq.gettime;
				tt.st = tt.et;
				tt.et = tt.st+tmpq.pt;
			} else {
				q.pop();
				tt.gt = tmp.gettime;
				tt.st = tt.et;
				tt.et = tt.st+tmp.pt;
			}
			if(tt.st >= ET) {
				break;
			} else if(tt.et > ET) {
				tt.et = ET;
			}
			Sum[tt.cnt]++;
//			printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, ((tt.st-tt.gt+59)/60));
			printf("%02d:%02d:%02d %02d:%02d:%02d %.0f\n", tt.gt/3600, (tt.gt-tt.gt/3600*3600)/60, tt.gt%60, tt.st/3600, (tt.st-tt.st/3600*3600)/60, tt.st%60, round((tt.st-tt.gt)/60.0));
		}
		a.push(tt);
		all++;
	}
	for(int i=0; i<k-1; i++) {
		printf("%d ", Sum[i]);
	}
	printf("%d\n", Sum[k-1]);

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值