PAT A1026 Table Tennis [硬核模拟]

题目描述

链接
k张桌子,球员到达后总是选择编号最小的桌子。如果训练时间超过2h会被压缩成2h,如果到达时候没有球桌空闲就变成队列等待。
k张桌子中m张是vip桌,如果vip桌子有空闲,而且队列里面有vip成员,那么等待队列中的第一个vip球员会到最小的vip球桌训练。如果vip桌子空闲但是没有vip来,那么就分配给普通的人。如果没有vip球桌空闲,那么vip球员就当作普通人处理。
给出每个球员的到达时间、要玩多久、是不是vip(是为1不是为0)。给出球桌数和所有vip球桌的编号,QQ所有在关门前得到训练的球员的到达时间、训练开始时间、等待时长(取整数,四舍五入),营业时间为8点到21点。如果再21点后还没有开始玩的人,就不再玩,不需要输出~

分析

建立两个结构体,person 和 tablenode,分别创建他们的结构体数组player和table。
因为给出的输入是无序的所以要先排序。可以根据最早空闲的桌子是不是vip桌进行分类讨论。
如果最早空闲的桌子index是vip桌,那么寻找队列里面第一个vip球员。根据他的到达时间继续分类讨论。
如果最早空闲的桌子index不是vip桌,那么看队首的球员是不是vip球员。如果是普通人,就直接把球桌分配给他,如果是vip,那么需要找到最早空闲的vip桌子的号vipindex,根据vip球员的到达时间和vipindex桌子的空闲时间继续分类讨论。
分配的时候标记table的num++,统计该table服务的人数。

  • 当然我不是这样做的

我的代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 10000 + 10;

struct node{
    int enter;
    int st;
    int cost;
    int ed;
    int tag;
    int use;
}nodes[maxn];

struct table{
    int tag;
    int ed;
    int cnt;
}tables[maxn];


int cal(int h,int m,int s){
    return h*3600 + m*60 + s;
}

void trans(int sum, int &h, int &m, int &s){
    h = sum / 3600;
    m = sum % 3600 / 60;
    s = sum % 60;
}

bool cmp(node x, node y){
    return x.enter < y.enter;
}

int hh,mm,ss,p,tag,k,m,n;

int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d:%d:%d %d %d",&hh,&mm,&ss,&p,&tag);
        nodes[i].enter = cal(hh,mm,ss);
        nodes[i].cost = p*60;
        nodes[i].tag = tag;
    }
    scanf("%d%d",&k,&m);
    for(int i=0;i<m;i++){
        int tmp;
        scanf("%d",&tmp);
        tables[tmp-1].tag = 1;
    }
    sort(nodes,nodes+n,cmp);
    for(int i=0;i<n;i++){
        if(nodes[i].use == 1) continue;
        int min = 0;
        for(int j=0;j<k;j++){
            if(tables[min].ed > tables[j].ed){
                min = j;
            }
        }
        if(tables[min].ed <= nodes[i].enter){ //进来时,已经有桌子可用
            nodes[i].use = 1;
            int h,m,s;
            trans(nodes[i].enter, h, m, s);
            printf("%02d:%02d:%02d ",h,m,s);
            nodes[i].st = nodes[i].enter;
            printf("%02d:%02d:%02d 0\n",h,m,s);
            tables[min].ed = nodes[i].st + nodes[i].cost;
            tables[min].cnt++;
        }else{ //需要等待
            if(tables[min].ed >= 21*3600) continue;
            if(tables[min].tag == 0){ //普通桌子,按序分配
                nodes[i].use = 1;
                int h,m,s;
                trans(nodes[i].enter, h, m, s);
                printf("%02d:%02d:%02d ",h,m,s);
                nodes[i].st = tables[min].ed;
                trans(nodes[i].st, h, m, s);
                printf("%02d:%02d:%02d %d\n",h,m,s, (int)round((nodes[i].st-nodes[i].enter)/60.0));
                tables[min].ed = nodes[i].st + nodes[i].cost;
                tables[min].cnt++;
            }else{
                int flag = 0; //标记是否有VIP用户在队列里
                for(int q=i; q<n && nodes[q].enter < tables[min].ed; q++){
                    if(nodes[q].tag == 1 && nodes[q].use == 0){ //执行分配
                        nodes[q].use = 1;
                        int h,m,s;
                        trans(nodes[q].enter, h, m, s);
                        printf("%02d:%02d:%02d ",h,m,s);
                        nodes[q].st = tables[min].ed;
                        trans(nodes[q].st, h, m, s);
                        printf("%02d:%02d:%02d %d\n",h,m,s, (int)round((nodes[q].st-nodes[q].enter)/60.0));
                        tables[min].ed = nodes[q].st + nodes[q].cost;
                        tables[min].cnt++;
                        flag = 1;
                        break;
                    }
                }
                if(flag){
                    i--;
                }else{ //没有的话
                    nodes[i].use = 1;
                    int h,m,s;
                    trans(nodes[i].enter, h, m, s);
                    printf("%02d:%02d:%02d ",h,m,s);
                    nodes[i].st = tables[min].ed;
                    trans(nodes[i].st, h, m, s);
                    printf("%02d:%02d:%02d %d\n",h,m,s, (int)round((nodes[i].st-nodes[i].enter)/60.0));
                    tables[min].ed = nodes[i].st + nodes[i].cost;
                    tables[min].cnt++;
                }
            }
        }
    }
    for(int i=0;i<k;i++){
        if(i!=0) printf(" ");
        printf("%d",tables[i].cnt);
    }
    printf("\n");
}

别人的代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
struct person {
    int arrive, start, time;
    bool vip;
}tempperson;
struct tablenode {
    int end = 8 * 3600, num;
    bool vip;
};
bool cmp1(person a, person b) {
    return a.arrive < b.arrive;
}
bool cmp2(person a, person b) {
    return a.start < b.start;
}
vector<person> player;
vector<tablenode> table;
void alloctable(int personid, int tableid) {
    if(player[personid].arrive <= table[tableid].end)
        player[personid].start = table[tableid].end;
    else
        player[personid].start = player[personid].arrive;
    table[tableid].end = player[personid].start + player[personid].time;
    table[tableid].num++;
}
int findnextvip(int vipid) {
    vipid++;
    while(vipid < player.size() && player[vipid].vip == false) vipid++;
    return vipid;
}
int main() {
    int n, k, m, viptable;
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {
        int h, m, s, temptime, flag;
        scanf("%d:%d:%d %d %d", &h, &m, &s, &temptime, &flag);
        tempperson.arrive = h * 3600 + m * 60 + s;
        tempperson.start = 21 * 3600;
        if(tempperson.arrive >= 21 * 3600) continue;
        tempperson.time = temptime <= 120 ? temptime * 60 : 7200;
        tempperson.vip = ((flag == 1) ? true : false);
        player.push_back(tempperson);
    }
    scanf("%d%d", &k, &m);
    table.resize(k + 1);
    for(int i = 0; i < m; i++) {
        scanf("%d", &viptable);
        table[viptable].vip = true;
    }
    sort(player.begin(), player.end(), cmp1);
    int i = 0, vipid = -1;
    vipid = findnextvip(vipid);
    while(i < player.size()) {
        int index = -1, minendtime = 999999999;
        for(int j = 1; j <= k; j++) {
            if(table[j].end < minendtime) {
                minendtime = table[j].end;
                index = j;
            }
        }
        if(table[index].end >= 21 * 3600) break;
        if(player[i].vip == true && i < vipid) {
            i++;
            continue;
        }
        if(table[index].vip == true) {
            if(player[i].vip == true) {
                alloctable(i, index);
                if(vipid == i) vipid = findnextvip(vipid);
                i++;
            } else {
                if(vipid < player.size() && player[vipid].arrive <= table[index].end) {
                    alloctable(vipid, index);
                    vipid = findnextvip(vipid);
                } else {
                    alloctable(i, index);
                    i++;
                }
            }
        } else {
            if(player[i].vip == false) {
                alloctable(i, index);
                i++;
            } else {
                int vipindex = -1, minvipendtime = 999999999;
                for(int j = 1; j <= k; j++) {
                    if(table[j].vip == true && table[j].end < minvipendtime) {
                        minvipendtime = table[j].end;
                        vipindex = j;
                    }
                }
                if(vipindex != -1 && player[i].arrive >= table[vipindex].end) {
                    alloctable(i, vipindex);
                    if(vipid == i) vipid = findnextvip(vipid);
                    i++;
                } else {
                    alloctable(i, index);
                    if(vipid == i) vipid = findnextvip(vipid);
                    i++;
                }
            }
        }
    }
    sort(player.begin(), player.end(), cmp2);
    for(i = 0; i < player.size() && player[i].start < 21 * 3600; i++) {
        printf("%02d:%02d:%02d ", player[i].arrive / 3600, player[i].arrive % 3600 / 60, player[i].arrive % 60);
        printf("%02d:%02d:%02d ", player[i].start / 3600, player[i].start % 3600 / 60, player[i].start % 60);
        printf("%.0f\n", round((player[i].start - player[i].arrive) / 60.0));
    }
    for(int i = 1; i <= k; i++) {
        if(i != 1) printf(" ");
        printf("%d", table[i].num);
    }
    return 0;
}
posted @ 2019-08-21 09:21  Doragd  阅读(222)  评论(0编辑  收藏  举报