1026. Table Tennis (30)
1.整體思路為:先遍歷vip桌子和vip玩家,如果有匹配成功的,進行匹配;然後再遍歷一輪所有的桌子和等候的玩家,有匹配的進行匹配;
2.被卡的地方:
1)關於秒的四捨五入,是按照大於等於30秒,進一分鐘,小於30秒則捨去的原則;最後的一個測試用例就是檢驗這個30秒的
2)在遍歷所有的玩家時,由於可能存在已經被前面服務了的vip玩家,所以需要額外加一個處理,使得playIndex指向的是未被服務的玩家;
3)主要是忘記了遍歷vip玩家時,同樣存在2)中的問題,因為在遍歷所有玩家的時候,有可能vip玩家也被服務安排了,所以需要在遍歷vip玩家中加一個處理,使得vipIndex指向未被服務的vip玩家。
3.下面是一些比較重要的測試用例:
//邊緣測試例子
1
21:00:00 10 1
3 3
1 2 3
1
20:59:59 10 1
3 3
1 2 3
0
3 1
2
//vip桌子分配例子,有vip桌子時,優先把vip分到編號小的vip桌子,而不是編號小的vip桌子
4
06:00:00 30 1
08:00:00 30 1
10:00:00 30 1
12:00:00 30 1
5 1
3
答案為:
06:00:00 08:00:00 120
08:00:00 08:00:00 0
10:00:00 10:00:00 0
12:00:00 12:00:00 0
1 0 3 0 0
//超過兩小時的例子
2
18:00:00 180 1
20:00:00 60 1
1 1
1
答案為:
18:00:00 18:00:00 0
20:00:00 20:00:00 0
2
//關於四捨五入為1分鐘的例子,大約等於30秒才+1分鐘,小於30則不+
3
07:59:31 60 1
07:59:29 60 1
08:00:30 100 1
2 1
1
答案為:
1
07:59:29 08:00:00 1
07:59:31 08:00:00 0
08:00:30 09:00:00 60
2 1
AC的原始碼:
//#include<string> //#include <iomanip> #include<vector> #include <algorithm> //#include<stack> #include<set> #include<queue> #include<map> //#include<unordered_set> //#include<unordered_map> //#include <sstream> //#include "func.h" //#include <list> #include<stdio.h> #include<iostream> #include<string> #include<memory.h> #include<limits.h> using namespace std; #define maxServe 46810 /* //正常的檢測例子,全部為普通玩家 9 20:52:00 10 0 08:00:00 20 0 08:02:00 30 0 20:51:00 10 0 08:10:29 5 0 08:12:00 10 0 20:50:00 10 0 08:01:30 15 0 20:53:00 10 0 3 1 2 答案為: 08:00:00 08:00:00 0 08:01:30 08:01:30 0 08:02:00 08:02:00 0 08:10:29 08:16:30 6 08:12:00 08:20:00 8 20:50:00 20:50:00 0 20:51:00 20:51:00 0 20:52:00 20:52:00 0 3 3 2 //正常的測試例子,沒有vip table 9 20:52:00 10 0 08:00:00 20 0 08:02:00 30 0 20:51:00 10 0 08:10:00 5 0 08:12:00 10 1 20:50:00 10 0 08:01:30 15 1 20:53:00 10 1 3 0 答案為: 08:00:00 08:00:00 0 08:01:30 08:01:30 0 08:02:00 08:02:00 0 08:10:00 08:16:30 7 08:12:00 08:20:00 8 20:50:00 20:50:00 0 20:51:00 20:51:00 0 20:52:00 20:52:00 0 3 3 2 //正常的測試例子,有vip和viptable 9 20:52:00 10 0 07:59:59 20 0 08:02:00 30 0 20:51:00 10 0 08:10:00 5 0 08:12:00 10 1 20:50:00 10 0 08:01:30 15 1 20:53:00 10 1 3 1 2 答案為: 07:59:59 08:00:00 0 08:01:30 08:01:30 0 08:02:00 08:02:00 0 08:12:00 08:16:30 5 08:10:00 08:20:00 10 20:50:00 20:50:00 0 20:51:00 20:51:00 0 20:52:00 20:52:00 0 3 3 2 //邊緣測試例子 1 21:00:00 10 1 3 3 1 2 3 1 20:59:59 10 1 3 3 1 2 3 0 3 1 2 //vip桌子分配例子,有vip桌子時,優先把vip分到編號小的vip桌子,而不是編號小的vip桌子 4 06:00:00 30 1 08:00:00 30 1 10:00:00 30 1 12:00:00 30 1 5 1 3 答案為: 06:00:00 08:00:00 120 08:00:00 08:00:00 0 10:00:00 10:00:00 0 12:00:00 12:00:00 0 1 0 3 0 0 //超過兩小時的例子 2 18:00:00 180 1 20:00:00 60 1 1 1 1 答案為: 18:00:00 18:00:00 0 20:00:00 20:00:00 0 2 //關於四捨五入為1分鐘的例子,大約等於30秒才+1分鐘,小於30則不+ 3 07:59:31 60 1 07:59:29 60 1 08:00:30 100 1 2 1 1 答案為: 1 07:59:29 08:00:00 1 07:59:31 08:00:00 0 08:00:30 09:00:00 60 2 1 */ string int2str(int a) { char n = a / 10 + '0'; char m = a % 10 + '0'; string tmp = ""; tmp += n; tmp += m; return tmp; } int char2int(char a) { int tmp = a - '0'; return tmp; } int time2int(string a) { int hour = char2int(a[0]) * 10 + char2int(a[1]) - 8; int min = char2int(a[3]) * 10 + char2int(a[4]); int sec = char2int(a[6]) * 10 + char2int(a[7]); return hour * 3600 + min * 60 + sec; } struct playerNode{ string arrive; int playTime, waitTime, serve; bool isVip; string serveStr(); int waitInt(); int serveTableNum; playerNode() :arrive(""), serve(maxServe), playTime(0), waitTime(0), isVip(false){}; playerNode(string a, int p, bool v) :arrive(a), serve(maxServe), playTime(p), waitTime(0), isVip(v){}; }; string playerNode::serveStr() { int hour = serve / 3600; int min = (serve - hour * 3600) / 60; int sec = serve % 60; return int2str(hour + 8) + ":" + int2str(min) + ":" + int2str(sec); } int playerNode::waitInt() { int diff = serve - time2int(arrive); int min = diff / 60; if (diff % 60 >= 30) min++; return min; } struct tableNode{ bool isVip; int playIndex;//當前玩家index int serveNum;//已經服務的玩家數量 tableNode() :isVip(false), playIndex(-1), serveNum(0) {}; }; bool cmp(const playerNode&a, const playerNode&b) { return a.arrive < b.arrive; } bool cmp2(const playerNode&a, const playerNode&b) {//按照服務時間排序 return a.serve < b.serve; } int main(void) { int playerNum; cin >> playerNum; vector<playerNode> player(playerNum); vector<int> vipPlayer(0); for (int i = 0; i < playerNum; i++) {//輸入玩家資訊 string arrive; int playTime; bool isVip; cin >> arrive >> playTime >> isVip; if (playTime > 120) playTime = 120; playTime *= 60; player[i].arrive = arrive; player[i].playTime = playTime; player[i].isVip = isVip; } sort(player.begin(), player.end(), cmp); for (int i = 0; i < playerNum; i++) {//建立vip佇列 if (player[i].isVip) vipPlayer.push_back(i); } int tableNum; int vipTableNum; cin >> tableNum >> vipTableNum; vector<tableNode> table(tableNum); vector<int> vipTable(0); int vipIndex = 0; int playerIndex = 0; for (int i = 0; i < vipTableNum; i++) {//輸入vip桌子 int a; cin >> a; table[a - 1].isVip = true; vipTable.push_back(a - 1); } for (int now = 0; now < 13 * 3600; now++) { for (int i = 0; i < table.size(); i++) {//遍歷所有桌子,處理正在玩的玩家 if (table[i].playIndex != -1) {//桌子有人 player[table[i].playIndex].playTime--; if (player[table[i].playIndex].playTime <= 0) {//清空桌子 table[i].playIndex = -1; } } } if (vipIndex < vipPlayer.size()) {//先服務vip玩家 for (int j = 0; j < vipTable.size(); j++) { while (vipIndex < vipPlayer.size() && player[vipPlayer[vipIndex]].serve != maxServe) {//跳過已經被服務的vip玩家,主要卡在這裡 vipIndex++; } int i = vipTable[j];//用i表示vip桌子 if (table[i].playIndex == -1 && vipIndex < vipPlayer.size() && time2int(player[vipPlayer[vipIndex]].arrive) <= now) { table[i].serveNum++; table[i].playIndex = vipPlayer[vipIndex]; player[vipPlayer[vipIndex]].serveTableNum = i; player[vipPlayer[vipIndex]].serve = now; vipIndex++; } } } if (playerIndex < player.size()) {//服務剩下的玩家,普通玩家和vip玩家混在一起 for (int i = 0; i < table.size(); i++) { while (playerIndex < player.size() && player[playerIndex].serve != maxServe) {//確保當前playerIndex的玩家是沒有被服務的 playerIndex++; } if (table[i].playIndex == -1 && playerIndex < player.size() && time2int(player[playerIndex].arrive) <= now) { table[i].serveNum++; table[i].playIndex = playerIndex; player[playerIndex].serveTableNum = i; player[playerIndex].serve = now; playerIndex++; } } } } sort(player.begin(), player.end(), cmp2); for (int i = 0; i < player.size(); i++) { if (player[i].serve != maxServe) { cout << player[i].arrive << " " << player[i].serveStr() << " " << player[i].waitInt() /*<< " " << player[i].serveTableNum*/ << endl; } } for (int i = 0; i < table.size(); i++) { cout << table[i].serveNum; if (i != table.size() - 1) cout << " "; } return 0; }