日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

1026. Table Tennis (30)

發布時間:2023/11/30 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 1026. Table Tennis (30) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目如下:

A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For any pair of players, if there are some tables open when they arrive, they will be assigned to the available table with the smallest number. If all the tables are occupied, they will have to wait in a queue. It is assumed that every pair of players can play for at most 2 hours.

Your job is to count for everyone in queue their waiting time, and for each table the number of players it has served for the day.

One thing that makes this procedure a bit complicated is that the club reserves some tables for their VIP members. When a VIP table is open, the first VIP pair in the queue will have the priviledge to take it. However, if there is no VIP in the queue, the next pair of players can take it. On the other hand, if when it is the turn of a VIP pair, yet no VIP table is available, they can be assigned as any ordinary players.

Input Specification:

Each input file contains one test case. For each case, the first line contains an integer N (<=10000) - the total number of pairs of players. Then N lines follow, each contains 2 times and a VIP tag: HH:MM:SS - the arriving time, P - the playing time in minutes of a pair of players, and tag - which is 1 if they hold a VIP card, or 0 if not. It is guaranteed that the arriving time is between 08:00:00 and 21:00:00 while the club is open. It is assumed that no two customers arrives at the same time. Following the players' info, there are 2 positive integers: K (<=100) - the number of tables, and M (< K) - the number of VIP tables. The last line contains M table numbers.

Output Specification:

For each test case, first print the arriving time, serving time and the waiting time for each pair of players in the format shown by the sample. Then print in a line the number of players served by each table. Notice that the output must be listed in chronological order of the serving time. The waiting time must be rounded up to an integer minute(s). If one cannot get a table before the closing time, their information must NOT be printed.

Sample Input: 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 1 2 Sample Output: 08:00:00 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


題目要求對乒乓球廳的事件進行模擬。

根據用戶到達時間排隊,有空桌子則按先到先服務的原則處理,如果隊列中有VIP用戶并且有VIP桌子空閑,則VIP可以“自成一隊”,按照到達順序直接分配到VIP桌,如果沒有VIP桌空閑,則VIP和普通用戶同樣對待。如果隊中沒有VIP并且編號最小的恰是VIP桌,普通用戶也可以使用VIP桌。

這類題目需要處理桌子的空閑與用戶的到達、服務時間之間的關系,需要有一個較好的思路,否則很容易混亂。

一個比較好的思路是為每個桌子設定空閑時間,首先全部初始化為上午8:00,當處理一個人時,首先從桌子列表最前面取到桌子,然后根據自己的到達時間和桌子的空閑時間即可計算出桌子的新空閑時間、用戶的等待時間和服務時間(有可能到關門時達不到預期服務時間)。

這道題麻煩在VIP上,如果有VIP用戶,他們可以“插隊”,要處理這些用戶,就會讓問題變得復雜,不能簡單的取出第一個未服務用戶和第一個桌子,而是要考慮有VIP用戶和VIP桌子的情況,這里有兩種優秀的解法:

①類似歸并排序的思想,維護普通用戶和VIP用戶兩個隊列。

②僅使用一個隊列,先考慮VIP情況,沒有VIP被處理則按照正常情況處理,算法來自sunbaigui。

我完整的參考了sunbaigui的解法,他的解法非常巧妙,下面羅列一下關鍵點:

①對用戶排序后從前到后處理,初始化服務開始時間為INF,這樣當處理完一個人時,他的服務時間不再是INF,由此判斷是否處理完畢,不必另設標志。

②不對桌子排序,而是找到所有桌子中空閑時間最早的,從桌子列表從前到后篩選,這樣就保證了按照編號的順序,十分巧妙。

③根據②中找到的最早空閑時間,找出所有符合的桌子和用戶,分別存儲一個新的容器,后面就針對這兩個新的容器處理。

④分情況討論,單人單桌、多人單桌、多人多桌,在這三種情況下分別判斷是否有VIP被服務。

⑤如果④中沒有VIP被服務,則取出新容器中第一個用戶和第一個桌子,正常處理。

下面的代碼來自sunbaigui,我在他代碼的基礎上加了些注釋,方便理解。

#include<iostream> #include<vector> #include<set> #include<map> #include<queue> #include<algorithm> #include<string> #include<string.h> #include<stdio.h>using namespace std;typedef struct Node {int arrive, process, tag;int serve, wait; // serve和wait分別代表服務開始時間和等待時間,將serve初始化為INF,從而區分有沒有被服務 }Node; typedef struct Table {int tag;int freeTime, num; // 每個桌子記錄自己的空閑時間和服務數,全部初始化為上午8:00,這樣可以迭代著處理 }Table; bool CmpArrive(Node a, Node b) // 用于對用戶的到達時間升序排序 {return a.arrive < b.arrive; } bool CmpServe(Node a, Node b) // 對用戶按照時間順序排列,優先按照服務時間排序,如果服務同時開始(多個空桌),按照到達時間升序 {if(a.serve == b.serve)return a.arrive < b.arrive;else return a.serve < b.serve; } #define INF 0x6FFFFFFFvector<Node> user; vector<Table> table; void UpdateInfo(int userID, int tableID) {user[userID].serve = max(user[userID].arrive, table[tableID].freeTime);user[userID].wait = user[userID].serve-user[userID].arrive;table[tableID].num++;table[tableID].freeTime = user[userID].serve+min(user[userID].process, 7200); // 最長服務時間為2小時 } int main() {//inputint n;scanf("%d",&n);user.resize(n);for(int i = 0; i < n; ++i){int h, m, s;scanf("%d:%d:%d %d%d",&h,&m,&s,&user[i].process,&user[i].tag);user[i].arrive = h*3600+m*60+s;user[i].process *= 60;user[i].serve = INF; user[i].wait = INF; // 初始化為INF,INF就代表未被處理}int k, m;scanf("%d%d",&k,&m);table.resize(k);for(int i = 0; i < k; ++i)table[i].freeTime = 8*3600, table[i].tag = 0, table[i].num = 0; // 所有桌子從上午8:00開始可用for(int i = 0; i < m; ++i){int c;scanf("%d",&c); c--;table[c].tag = 1;}//processsort(user.begin(), user.end(), CmpArrive); // 按照到達時間升序排列,符合排隊規則//visited.assign(n, false);for(int i = 0; i < n; ++i){if(user[i].serve != INF) continue; // server時間初始化為INF,不為INF的已經服務完畢。int minFreeTime = INF;for(int j = 0; j < k; ++j)minFreeTime = min(minFreeTime, table[j].freeTime); // 找出最早空閑的桌子int timePoint = max(user[i].arrive, minFreeTime); // 根據隊頭用戶確定當前最早服務時間點if(timePoint >= 21*3600) break; // 判斷是否超過營業時間vector<int> userList;vector<int> tableList;for(int j = i; j < n; ++j) // 根據最早服務時間點找到所有可能被服務的人,是為了處理有VIP優先去VIP桌的情況。if(user[j].serve == INF && user[j].arrive <= timePoint) userList.push_back(j);for(int j = 0; j < k; ++j) // 找出所有在時間點之前空閑的桌子,因為可能用戶到達晚,因此會有多個桌子空閑if(table[j].freeTime <= timePoint) tableList.push_back(j);bool flag = false; // 判斷是否處理了一個服務// 首先特殊處理VIP,如果沒有VIP被處理則處理一個普通用戶,每次只處理一個if(userList.size() == 1 && tableList.size() > 1) // 單個用戶多個桌子,用戶為VIP則去找編號最小的VIP桌{if(user[userList[0]].tag == 1){for(int j = 0; j < tableList.size(); ++j){if(table[tableList[j]].tag == 1){flag = true;UpdateInfo(userList[0], tableList[j]);break;}}}}else if(tableList.size() == 1 && userList.size() > 1) // 多人單桌情況,如果為VIP桌找多人中最先到達的VIP為其服務{if(table[tableList[0]].tag == 1){for(int j = 0; j < userList.size(); ++j){if(user[userList[j]].tag == 1){flag = true;UpdateInfo(userList[j], tableList[0]);break;}}}}else if(tableList.size() > 1 && userList.size() > 1) // 多人多桌情況,先找桌子中的VIP桌,有則找用戶中最先到達的VIP{for(int t = 0; t < tableList.size(); ++t){if(table[tableList[t]].tag == 1){for(int u = 0; u < userList.size(); ++u){if(user[userList[u]].tag == 1){flag = true;UpdateInfo(userList[u], tableList[t]);break;}}}}}if(!flag) UpdateInfo(userList[0], tableList[0]); // 如果沒有VIP被處理,則按照正常情況處理。--i;}//outputsort(user.begin(), user.end(), CmpServe);for(int i = 0; i < n; ++i){if(user[i].serve >= 21*3600) break;int h1, m1, s1, h2, m2, s2;int t = user[i].arrive;h1 = t/3600; t %= 3600;m1 = t/60; t %= 60;s1 = t;t = user[i].serve;h2 = t/3600; t %= 3600;m2 = t/60; t %= 60;s2 = t;// 注意對等待時間的四舍五入為超過30秒算作一分鐘printf("%02d:%02d:%02d %02d:%02d:%02d %d\n", h1, m1, s1, h2, m2, s2, (user[i].wait+30)/60);}for(int i = 0; i < k; ++i){if(i != k-1)printf("%d ",table[i].num);else printf("%d\n",table[i].num);}return 0; }

轉載于:https://www.cnblogs.com/aiwz/p/6154036.html

總結

以上是生活随笔為你收集整理的1026. Table Tennis (30)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。