PAT甲级_1026 Table Tennis (30 分)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44705116/article/details/102513257

我现在只希望考试的时候不会碰到这种题

定义球员与球桌的结构体;输入时按到达时间排一次序,输出时按开始时间排一次序,定义两次的函数;

#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;

struct player
{
	int arrive, start, cost;
	bool vip;
}temp;

struct table {
	int end = 28800, id;
	bool vip;
};

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

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

定义球员对应球桌的函数;同时定义更新vip下标的函数。


vector<player> tempplayer;
vector<table> temptable;

void tabling(int playerid, int tableid) {
	if (tempplayer[playerid].arrive <= temptable[tableid].end) {
		tempplayer[playerid].start = temptable[tableid].end;
	}
	else {
		tempplayer[playerid].start = tempplayer[playerid].arrive;
	}
	temptable[tableid].end = tempplayer[playerid].start+tempplayer[playerid].cost;
	temptable[tableid].id++;
}

int nextvip(int vip) {
	vip++;
	while (vip < tempplayer.size() && tempplayer[vip].vip == false) {
		vip++;
	}
	return vip;
}

写出输入部分,将时间都化为秒方便计算;排除九点及以后到的人;

int main() {
	int n, h, m, s, lon, flag;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d:%d:%d %d %d", &h, &m, &s, &lon, &flag);
		temp.arrive = h * 3600 + m * 60 + s;
		temp.start = 75600;
		if (temp.arrive >= 75600) continue;
		temp.cost = lon <= 120 ? lon * 60 : 7200;
		temp.vip = ((flag==1) ? true : false);
		tempplayer.push_back(temp);
	}
	int k, x, spe;
	scanf("%d%d", &k, &x);
	temptable.resize(k + 1);
	for (int i = 0; i < x; i++) {
		scanf("%d", &spe);
		temptable[spe].vip = true;
	}
	sort(tempplayer.begin(), tempplayer.end(),cmp1);
	```
	初始化完成,开始排序;注意等号、括号有无漏加!
	```
	int i = 0, vip = -1;
	vip=nextvip(vip);
	while (i < tempplayer.size()) {
		int index = -1, minend = 99999999;
		for (int j = 1; j <= k; j++) {
			if (temptable[j].end < minend) {
				minend = temptable[j].end;
				index = j;
			}
		}

找出当前最早空出的桌子后,写出在九点前结束的判断条件(不要漏=);在当前球员是vip会员但标号小于当前vip时说明该球员以及打过球,vip下标已经更新,故跳过该球员;

		if (minend >= 75600) break;
		if (tempplayer[i].vip == true && i < vip) {
			i++;
			continue;
		}

分四种情况讨论:当前球桌是/否vip,当前球员是/否vip;是vip桌时查看队列中是否有vip…分情况讨论,并及时更新vip下标。

		if (temptable[index].vip == true) {
			if (tempplayer[i].vip == true) {
				tabling(i, index);
				if (i == vip) {
					vip = nextvip(vip);
				}
				i++;
			}
			else {
				if (vip < tempplayer.size() && tempplayer[vip].arrive <= temptable[index].end) {
					tabling(vip, index);
					vip = nextvip(vip);
				}
				else {
					tabling(i, index);
					i++;
				}
			}
		}
		else {
			if (tempplayer[i].vip == false) {
				tabling(i, index);
				i++;
			}
			else {
				int vipindex = -1, vipend = 99999999;
				for (int j = 1; j <= k; j++) {
					if (temptable[j].vip == true && temptable[j].end < vipend) {
						vipend = temptable[j].end;
						vipindex = j;
					}
				}
				if (vipindex != -1 && tempplayer[i].arrive >= temptable[vipindex].end) {
					tabling(i, vipindex);
					if (vip == i)
						vip = nextvip(vip);
					i++;
				}
				else {
					tabling(i, index);
					if (vip == i) {
						vip = nextvip(vip);
					}
					i++;
				}
			}
		}
	}
	sort(tempplayer.begin(), tempplayer.end(), cmp2);

写输出部分时注意round函数的书写;

	for (int i = 0; i < tempplayer.size()&&tempplayer[i].start<75600; i++) {
		printf("%02d:%02d:%02d ", tempplayer[i].arrive / 3600, tempplayer[i].arrive % 3600 / 60, tempplayer[i].arrive % 60);
		printf("%02d:%02d:%02d ", tempplayer[i].start / 3600, tempplayer[i].start % 3600 / 60, tempplayer[i].start % 60);
		printf("%.0f\n", round((tempplayer[i].start - tempplayer[i].arrive) / 60.0));
	}	 
	for (int i = 1; i <= k; i++) {
		if (i != 1) printf(" ");
		printf("%d", temptable[i].id);
	}
	return 0;                                                 
}

猜你喜欢

转载自blog.csdn.net/weixin_44705116/article/details/102513257