1026 Table Tennis (僅26分)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章