【1026 30 大模拟】 Table Tennis
传送门
题意
给定 \(n\) 个人,每个人有一个到达时间和游玩时长,时长最多为 \(2h\) ,分为普通用户和 \(vip\) 用户,\(k\) 个台球桌, 给定 \(m\) 个 \(vip\) 球桌 \(id\) , 如果 \(vip\) 桌有空闲,⽽且队列里有 \(vip\),那么等待队列中的第一个 \(vip\) 会到最⼩的 \(vip\) 球桌。如果 \(vip\) 桌空闲但是没有 \(vip\) ,就分配给普通人。如果没有 \(vip\) 球桌空闲,那么\(vip\) 球员就当作普通人处理。营业时间为 \(08:00:00 \sim 21:00:00\) 超过的不能玩,求出每个人到达时间、开始时间、等待时长(取整数,四舍五⼊),以及每个桌子上游玩的人数
数据范围
\(n\leq 10000\)
\(k\leq 100,m<k\)
题解
- 存在等待队列中有普通和
vip的情况,这样vip更优先分配给vip_tables - 所有玩家的游戏时间最长为 2 小时
- 建立事件结构体,桌子编号为
-1表示待分配的玩家,为正常桌子编号则表示当前桌子被占用 - 按照时间来进行事件的处理,存下空闲的所有桌子和
vip桌子- 如果当前是被占用的桌子就释放掉
- 如果当前是
vip桌,且有等待的vip玩家,分类 - 否则按照队列第一个进行分配
- 如果当前是
- 如果当前是待分配的玩家
- 如果是
vip玩家且有空闲vip桌分配 - 如果有空闲桌,分配第一个
- 如果没有空闲的加入等待队列
- 如果是
- 如果当前是被占用的桌子就释放掉
Code
#include <bits/stdc++.h>
using namespace std;
struct Player {
int arrive, serve, vip;
};
struct Action{
int table_id, player_id, time;
bool operator < (const Action& a ) const {
return time > a.time;
}
};
void output(int time) {
cout << setfill('0') << setw(2) << time / 3600 << ":" << setw(2)
<< time % 3600 / 60 << ":" << setw(2) << time % 60 << " ";
}
int main() {
int n; cin >> n;
priority_queue<Action> actions;
int end_time = 21 * 3600;
vector<Player> players;
for (int i = 0; i < n; i++) {
int h, m, s, s_t, v; char c;
cin >> h >> c >> m >> c >> s >> s_t >> v;
players.push_back({h * 3600 + m * 60 + s, min(120, s_t) * 60, v});
actions.push({-1, i, players[i].arrive});
}
int k, m; cin >> k >> m;
set<int> free_tables, free_vip_tables;
list<int> wait_players, wait_vip_players;
vector<bool> is_vip(k, false);
vector<int> ans(k, 0);
for (int i = 0; i < m; i++) {
int idx; cin >> idx; idx--;
is_vip[idx] = 1;
}
for (int i = 0; i < k; i++) {
if (is_vip[i]) free_vip_tables.insert(i);
free_tables.insert(i);
}
while (not actions.empty()) {
auto a = actions.top();
actions.pop();
if (a.time >= end_time) break;
if (a.table_id == -1) {
Player& this_player = players[a.player_id];
int table_id = -1;
if (free_tables.size()) {
if (players[a.player_id].vip and free_vip_tables.size()) {
table_id = *free_vip_tables.begin();
free_tables.erase(table_id);
free_vip_tables.erase(table_id);
} else {
table_id = *free_tables.begin();
free_tables.erase(table_id);
if (is_vip[table_id]) free_vip_tables.erase(table_id);
}
output(this_player.arrive);
output(this_player.arrive);
cout << 0 << endl;
actions.push({table_id, a.player_id, this_player.arrive + this_player.serve});
ans[table_id]++;
} else {
if (this_player.vip) wait_vip_players.push_back(a.player_id);
wait_players.push_back(a.player_id);
}
} else {
if (wait_players.empty()) {
free_tables.insert(a.table_id);
if (is_vip[a.table_id]) free_vip_tables.insert(a.table_id);
} else {
int player_id = -1;
if (wait_vip_players.size() and is_vip[a.table_id]) {
player_id = wait_vip_players.front();
wait_vip_players.pop_front();
wait_players.erase(find(wait_players.begin(), wait_players.end(), player_id));
} else {
player_id = wait_players.front();
wait_players.pop_front();
if (players[player_id].vip) wait_vip_players.pop_front();
}
Player& this_player = players[player_id];
output(this_player.arrive);
output(a.time);
cout << round((a.time - this_player.arrive) / 60.0) << endl;
actions.push({a.table_id, player_id, a.time + this_player.serve});
ans[a.table_id]++;
}
}
}
for (int i = 0; i < k; i++) {
if (i) cout << ' ';
cout << ans[i];
}
return 0;
}

浙公网安备 33010602011771号