5-30 Table Tennis (30分)

原题

一看就是模拟题, 但就是有些细节有点繁琐..
题意大概是维护一些桌子, 有人来的时候如果有桌子就分配,没有桌子就让他们等待下一张空闲的桌子。

只不过还有一些特殊的VIP桌子和VIP用户,如果当前有空闲的VIP桌子,那就优先分配给已经到达的且当前正在等待队列中的那些VIP用户。若没有空闲的VIP桌子则VIP用户视为普通用户处理。

我的主要思路就是按时间点(currentTime)推进的顺序来逐一处理事件。到达一个新的时间点的时候,首先检查是否可以把VIP桌子分配给VIP用户。之后检查普通的桌子是否能够分配给哪个用户。第三步就是更新时间点currentTime为下一个需要进行处理的时间点。

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cctype>
#include <stack>
#include <list>
#include <vector>
#include <algorithm>

using namespace std;

const int StartTime = 8 * 60 * 60, EndTime = 21 * 60 * 60;

/*
计算过程中的时间均以秒为单位
*/

struct Pair {
    int arriveTime;
    int beginTime;
    int playTime;               // 将要玩的时间(以秒为单位, 【等于0则已经玩过】)
    int waitTime;               // 等待的时间
    bool isVip;
    Pair (int _a = 0, int _b = 0, bool _is = 0) : arriveTime (_a), playTime (_b), isVip(_is) { 
        beginTime = waitTime = 0; 
    }
};

int N, M, tblNum;
list<Pair> players;
int AvailableTime[101];             // 标记桌子下一次能用的时间
int Served[101];                                // 标记桌子用过次数
vector<int> vipTable;

bool CompByArrive (const Pair & p1, const Pair & p2) {
    return p1.arriveTime < p2.arriveTime;
}

bool CompByBegin (const Pair & p1, const Pair & p2) {
    return p1.beginTime < p2.beginTime;
}

int TimeToInt (char times[]) {
    int tmp = 0;
    char * result = strtok (times, ":");
    tmp += atoi (result) * 60;
    result = strtok (NULL, ":");
    tmp = (tmp + atoi (result) ) * 60;
    result = strtok (NULL, ":");
    tmp += atoi (result);
    return tmp;
}

string IntToTime (int time) {
    char result[20];
    int hour = time / ( 60 * 60 );
    time -= hour * 60 * 60;
    int minute = time / 60;
    time -= minute * 60;
    sprintf (result, "%02d:%02d:%02d", hour, minute, time);
    return string(result);
}

int nextPlayerTime ( ) {
    int earliest = EndTime;
    for ( auto it = players.begin ( ); it != players.end ( ); it++) {
        if( it->playTime > 0 )  earliest = min (it->arriveTime, earliest);
    }
    return earliest;
}

void SetPlayer (Pair & player, int tbl, int currentTime) {
    AvailableTime[tbl] = currentTime + min (player.playTime, 2 * 60 * 60);      // 最多用2小时
    player.beginTime = currentTime;
    player.waitTime = currentTime - player.arriveTime;
    player.playTime = 0;
    Served[tbl]++;
}

int main ( ) {
    char strings[20];
    int playtime, isVIP;
    Pair player;
    // 读入数据
    cin >> N;
    for ( int i = 1; i <= N; i++ ) {
        cin >> strings >> playtime >> isVIP;
        players.push_back (Pair (TimeToInt (strings), playtime * 60, isVIP));
    }
    cin >> tblNum >> M;
    for ( int i = 0, tmp; i < M; i++) {
        cin >> tmp;
        vipTable.push_back (tmp);
    }

    // 模拟
    int currentTime = StartTime;
    list<Pair>::iterator it_player;
    for ( int i = 1; i <= tblNum; i++){
        AvailableTime[i] = StartTime;
    }

    players.sort(CompByArrive);
    do {
        // 找VIP桌子
        for ( int i = 0; i < vipTable.size ( ); i++ ) {
            if ( AvailableTime[vipTable[i]] <= currentTime ) {
                for ( it_player = players.begin ( ); it_player != players.end ( ); it_player++ ) {
                    if ( it_player->isVip && it_player->arriveTime <= currentTime && it_player->playTime > 0  ) {
                        SetPlayer (*it_player, vipTable[i], currentTime);
                        break;                          // 注意分配完一张桌子一定要及时break否则继续找Pair很可能会再分配这张桌子第二次
                    }
                }
            }
        }
        // 找普通桌子
        for ( int i = 1; i <= tblNum; i++ ) {
            if ( AvailableTime[i] <= currentTime ) {
                for ( it_player = players.begin ( ); it_player != players.end ( ); it_player++ ) {
                    if ( it_player->playTime > 0 && it_player->arriveTime <= currentTime ) {
                        SetPlayer (*it_player, i, currentTime);
                        break;
                    }
                }
            }
        }
        // 更新下一次的时间
        currentTime = EndTime;
        for ( int i = 1; i <= tblNum; i++) {
            currentTime = min (currentTime, AvailableTime[i]);
        }
        currentTime = max (currentTime, nextPlayerTime ( ));
    } while ( currentTime < EndTime );

    players.sort (CompByBegin);
    for ( it_player = players.begin ( ); it_player != players.end ( ); it_player++) {
        if ( it_player->playTime == 0 ) {
            cout << IntToTime (it_player->arriveTime) << " " << IntToTime (it_player->beginTime) << " " <<
                ( it_player->waitTime + 30 )/ 60 << endl;
        }
    }
    for ( int i = 1; i <= tblNum; i++ ) {
        cout << Served[i] << ( i < tblNum ? " " : "\n" );
    }
    system ("pause");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
The following is the data that you can add to your input file (as an example). Notice that the first line is going to be a line representing your own hobbies. In my case, it is the Vitaly,table tennis,chess,hacking line. Your goal is to create a class called Student. Every Student will contain a name (String) and an ArrayList<String> storing hobbies. Then, you will add all those students from the file into an ArrayList<Student>, with each Student having a separate name and ArrayList of hobbies. Here is an example file containing students (the first line will always represent yourself). NOTE: eventually, we will have a different file containing all our real names and hobbies so that we could find out with how many people each of us share the same hobby. Vitaly,table tennis,chess,hacking Sean,cooking,guitar,rainbow six Nolan,gym,piano,reading,video games Jack,cooking,swimming,music Ray,piano,video games,volleyball Emily,crochet,drawing,gardening,tuba,violin Hudson,anime,video games,trumpet Matt,piano,Reading,video games,traveling Alex,swimming,video games,saxophone Roman,piano,dancing,art Teddy,chess,lifting,swimming Sarah,baking,reading,singing,theatre Maya,violin,knitting,reading,billiards Amy,art,gaming,guitar,table tennis Daniel,video games,tennis,soccer,biking,trumpet Derek,cooking,flute,gaming,swimming,table tennis Daisey,video games,guitar,cleaning,drawing,animated shows,reading,shopping Lily,flute,ocarina,video games,baking Stella,roller skating,sudoku,watching baseball,harp Sophie,viola,ukulele,piano,video games
最新发布
06-10

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值