【PAT甲级】1026. Table Tennis (30)

注:vip顾客面临多桌选择时,优先选择vip球桌。
注2:非vip顾客有多桌选择时,选id号最小的球桌。
注3:只有vip桌空出来的时候,vip顾客才能插队;非vip球桌空出来时,顾客(包括vip与非vip)中到达最早的先选。
#include <stdio.h>
#include <deque>
#include <algorithm>
#define OPEN_TIME 8 * 3600
#define CLOSE_TIME 21 * 3600
using namespace std;
typedef struct Table {
    int id;
    int time;
    int vip;
    int serNum;
} Table;
typedef struct Player {
    int arrTime;
    int serTime;
    int playTime;
    int waitTime;
    int vip;
    bool finished;
} Player;
void timeConversion (int t, int &h, int &m, int &s);
void serve(int s);
void serve2(int s);
bool pcom(Player a, Player b) {
    return a.arrTime < b.arrTime;
}
bool pcom_ser(Player a, Player b) {
    if (a.serTime < b.serTime) return true;
    else if (a.serTime == b.serTime && a.arrTime < b.arrTime) return true;
    return false;
}
bool tcom(Table a, Table b) {
    if (a.time < b.time) return true;
    else if (a.time == b.time && a.vip > b.vip) return true;
    else if (a.time == b.time && a.vip == b.vip && a.id < b.id) return true;
    return false;
}
bool tcom2(Table a, Table b) {
    if (a.time < b.time) return true;
    else if (a.time == b.time && a.vip < b.vip) return true;
    else if (a.time == b.time && a.vip == b.vip && a.id < b.id) return true;
    return false;
}
bool tcom_id(Table a, Table b) {
    return a.id < b.id;
}
bool tcom_vip_id(Table a, Table b) {
    if (a.vip > b.vip) return true;
    else if (a.vip == b.vip && a.id < b.id) return true;
    return false;
}

deque<Table> t;
Player p[10001];
int n, k, m;

int main(int argc, char *argv[]) {
    int i, j;
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        int h, m, s;
        scanf("%d:%d:%d %d %d", &h, &m, &s, &p[i].playTime, &p[i].vip);
        if (p[i].playTime > 120) p[i].playTime = 120;/
        p[i].playTime *= 60;
        p[i].arrTime = h * 3600 + m * 60 + s;
        p[i].finished = false;
        p[i].serTime = -1;
    }
    sort(p, p + n, pcom);
    int nn = n;
    for(i = nn - 1; i >= 0; i--) {
        if (p[i].arrTime >= CLOSE_TIME) n--;
    }
    scanf("%d %d", &k, &m);
    for (i = 1; i <= k; i++) {
        Table table;
        table.id = i;
        table.vip = 0;
        table.time = OPEN_TIME;
        table.serNum = 0;
        t.push_back(table);
    }
    for (i = 0; i < m; i++) {
        int d;
        scanf("%d", &d);
        t[d - 1].vip = 1;
    }
    int s = 0;
    while(s < n) {

        if (p[s].finished == true) {
            s++;
            continue;
        }
        sort(t.begin(), t.end(), tcom);
        if (t.front().time >= CLOSE_TIME) break;

        int tim = t.front().time;
        int ptim = p[s].arrTime;
        int tCount = 0;
        int pCount = 0;
        if (tim <= ptim) {
            for (i = 0; i < t.size() && t[i].time <= ptim; i++);
            tCount = i;
            sort(t.begin(), t.begin() + tCount, tcom_vip_id);
            if (tCount > 1) {//多个桌子可选
                if (p[s].vip == 1 && t.front().vip == 1) {
                    serve(s++);
                } else if (p[s].vip == 1 && t.front().vip == 0) {
                    serve(s++);
                } else if (p[s].vip == 0 && t.front().vip == 0) {
                    sort(t.begin(), t.begin() + tCount, tcom_id);
                    serve(s++);
                } else if (p[s].vip == 0 && t.front().vip == 1) {
                    sort(t.begin(), t.begin() + tCount, tcom_id);
                    serve(s++);
                }
            } else if (tCount == 1) {
                serve(s++);
            }
        } else if (tim > ptim) {
            for (i = 0; i < t.size() && t[i].time == tim; i++);
            tCount = i;
            if (t.front().vip == 1) {
                bool hasVip = false;
                for (i = s; i < n && p[i].arrTime <= tim; i++) {
                    if (p[i].finished == false && p[i].vip == 1) {
                        serve2(i);
                        hasVip = true;
                        p[i].finished = true;
                        break;
                    }
                }
                if (!hasVip) {
                    sort(t.begin(), t.begin() + tCount, tcom_id);
                    serve2(s++);
                }
            } else if (t.front().vip == 0) {
                sort(t.begin(), t.begin() + tCount, tcom_id);
                serve2(s++);
            }
        }
    }
    sort(p, p + n, pcom_ser);
    for (i = 0; i < n; i++) {
        if (p[i].finished == true) {
            int h, m, s;
            timeConversion(p[i].arrTime, h, m, s);
            printf("%02d:%02d:%02d ", h, m, s);
            timeConversion(p[i].serTime, h, m, s);
            printf("%02d:%02d:%02d ", h, m, s);
            printf("%d\n", (p[i].waitTime + 30) / 60);
        } else continue;
    }
    sort(t.begin(), t.end(), tcom_id);
    for (i = 0; i < t.size(); i++) {
        printf("%d", t[i].serNum);
        if (i < t.size() - 1) printf(" ");
        else printf("\n");
    }
    return 0;
}
void timeConversion (int t, int &h, int &m, int &s) {
    h = t / 3600;
    m = t % 3600 / 60;
    s = t % 3600 % 60;
}
void serve(int s) {
    p[s].serTime = p[s].arrTime;
    p[s].waitTime = 0;
    p[s].finished = true;
    t.front().time = p[s].arrTime + p[s].playTime;
    t.front().serNum++;
}
void serve2(int s) {
    p[s].serTime = t.front().time;
    p[s].waitTime = t.front().time - p[s].arrTime;
    p[s].finished = true;
    t.front().time += p[s].playTime;
    t.front().serNum++;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值