1026 Table Tennis

link

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

int N, K, M;
int endTime[101];
int isvipTable[101];
int playerComplete[10000];
int cnt[101];
struct Player {
    int arriveTime;
    int playTime;
    int isvip;
};
vector<Player> players;
int getseconds(int hh, int mm, int ss) {
    return hh * 3600 + mm * 60 + ss;
}

string getstr(int n) {
    int ss = n % 60;
    n /= 60;
    int mm = n % 60;
    n /= 60;
    int hh = n;
    char s[10];
    sprintf(s, "%02d:%02d:%02d", hh, mm, ss);
    return s;
}


void assign(int p, int table,int serve) {
    playerComplete[p] = 1;
    endTime[table] = serve+players[p].playTime;
    int wait = serve - players[p].arriveTime;
    wait = round(1.0 * wait / 60);
    cout << getstr(players[p].arriveTime) << " " << getstr(serve) << " " << wait << endl;
    cnt[table]++;
    //cout << getstr(players[p].arriveTime) << " " << table << " " << getstr(endTime[table]) << endl;
}

int main() {
    scanf("%d", &N);
    players=vector<Player>(N);
    for (int i = 0; i < N; i++) {
        int hh, mm, ss, t, v;
        scanf("%d:%d:%d %d %d", &hh, &mm, &ss, &t, &v);
        Player p;
        p.arriveTime = getseconds(hh, mm, ss);
        p.playTime = min(2*3600,t * 60);
        p.isvip = v;
        players[i] = p;
    }
    scanf("%d%d", &K, &M);
    for (int i = 1; i <= K; i++) endTime[i] = 8 * 3600;
    for (int i = 0; i < M; i++) {
        int a;
        scanf("%d", &a);
        isvipTable[a] = 1;
    }
    sort(players.begin(), players.end(), [](Player& p1, Player& p2) {
        return p1.arriveTime < p2.arriveTime;
        });
    //cout << players[0].playTime << endl;
    for (int i = 0; i < N; i++) {
        //cout << i << endl;
        if (playerComplete[i]) continue;
        if (players[i].arriveTime >= 21 * 3600) break;
        bool hasvacant = false;
        int minVacanttable = -1;
        int minVacantviptable = -1;
        for (int j = 1; j <= K; j++) {
            if (endTime[j] <= players[i].arriveTime) {
                if (minVacanttable == -1) minVacanttable = j;
                if (isvipTable[j]) {
                    if (minVacantviptable == -1) minVacantviptable = j;
                }
                hasvacant = true;
            }
        }
        //cout << i << " " << getstr(players[i].arriveTime) << endl;
        if (hasvacant) {
            if (players[i].isvip) {
                if (minVacantviptable != -1) {
                    assign(i, minVacantviptable, players[i].arriveTime);
                } else {
                    assign(i, minVacanttable, players[i].arriveTime);
                }
            } else {
                assign(i, minVacanttable, players[i].arriveTime);
            }
        } else {      // no vacant table  
            int minEndTime = INT_MAX;
            vector<int> candi;
            for (int j = 1; j <= K; j++) {
                if (endTime[j] < minEndTime) {
                    minEndTime = endTime[j];
                    candi.clear();
                    candi.push_back(j);
                } else if (endTime[j] == minEndTime) {
                    candi.push_back(j);
                }
            }
            if (minEndTime >= 21 * 3600) break;
            bool hasVipTable = false;
            int vipTable = -1;
            for (int j : candi) {
                if (isvipTable[j]) {
                    hasVipTable = true;
                    vipTable = j;
                    break;
                }
            }
            bool hasVipPlayer = false;
            int insertVip = -1;
            for (int j = i + 1; j < N; j++) {
                if (players[j].arriveTime > minEndTime) break;
                if (playerComplete[j]) continue;
                if (players[j].isvip) {
                    hasVipPlayer = true;
                    insertVip = j;
                    break;
                } 
            }
            if (players[i].isvip) {
                if (vipTable != -1) {
                    assign(i, vipTable, minEndTime);
                } else {
                    assign(i, candi[0], minEndTime);
                }
            } else {
                if (vipTable != -1) {
                    if (insertVip != -1) {
                        assign(insertVip, vipTable, minEndTime);
                        i--;
                    } else {
                        assign(i, candi[0], minEndTime);
                    }
                } else {
                    assign(i, candi[0], minEndTime);
                }
            }
        }
    }
    for (int i = 1; i <= K; i++) {
        if (i > 1) printf(" ");
        printf("%d", cnt[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/FEIIEF/p/12870829.html