PAT 1026 Table tennis

题目网址: https://www.patest.cn/contests/pat-a-practise/1026

看这个代码要比下面格式舒服一些: https://www.patest.cn/submissions/2199496/source

#include <iostream>
#include <queue>
#include <list>
#include <algorithm>
#include <stdio.h>
using namespace std;

#define MAX_N 10005
#define MAX_TABLE 105

struct Player
{
  string arrive_time;
  int n_arrive_time;

  int play_time;
  int vip;

  string serve_time;
  int n_serve_time;

  int wait_time;
}g_player[MAX_N];

struct Table
{
  int id; // 1 - N
  int vip;

  string end_time;
  int n_end_time;

  int count;
}g_table[MAX_TABLE];

int toInt(string const &time)
{
  int i;
  const char *tmp;
  int res = 0;

  for(i = 0; i < 3; ++i)
    {
      tmp = time.substr(i*3, 2).c_str();
      res = res * 60 + ((tmp[0]-'0') * 10 + (tmp[1]-'0'));
    }

  return(res);
}

void toChar(char s[], int ss)
{
  s[0] = ss / 10 + '0';
  s[1] = ss % 10 + '0';
  s[2] ='\0';
}

string toString(int time)
{
  int ss = time % 60;
  int mm = (time / 60) % 60;
  int hh = time / (60 * 60);

  char s[3], m[3], h[3];
  toChar(s, ss);
  toChar(m, mm);
  toChar(h, hh);

  string str = string(h) + ":" + string(m) +
    ":" + string(s);

  return(str);
}

bool player_comp(Player *a, Player *b)
{
  return(a->n_arrive_time < b->n_arrive_time);
}

struct table_comp
{
  bool operator()(Table *a, Table *b)
  {
    return(a->id > b->id);
  }
};

struct busy_table_comp
{
  bool operator()(Table *a, Table *b)
  {
    return(a->n_end_time > b->n_end_time);
  }
};

typedef priority_queue<Table *, vector<Table*>, table_comp> table_type;
typedef priority_queue<Table *, vector<Table*>, busy_table_comp> busy_table_type;

void assignTable(Player *player, Table *table, int cur_time)
{
  player->serve_time = toString(cur_time);
  player->n_serve_time = cur_time;
  player->wait_time = (cur_time - toInt(player->arrive_time) + 30) / 60;

  table->n_end_time = cur_time + player->play_time * 60;
  table->end_time = toString(table->n_end_time);
  ++table->count;
}

void processUtil(Player *player_arr[], int nplayer,
                 table_type &free_table,table_type &free_vip_table,
                 vector<Player*> &result)
{
  queue<Player *> wait_queue_vip;
  queue<Player *> wait_queue;

  int i, j;
  Table *table;
  Player *player;

  busy_table_type busy_table;

  int cur_time = 8 * 60 * 60;
  int end = 21 * 60 * 60;

  i = 0;
  for(; cur_time < end; ++cur_time)
    {
      // if someone is comming at this moment ...
      if(i < nplayer && cur_time == player_arr[i]->n_arrive_time)
        {
          if(player_arr[i]->vip == 1)
            wait_queue_vip.push(player_arr[i]);
          else
            wait_queue.push(player_arr[i]);

          ++i;
        }

      // update busy table
      for(;!busy_table.empty() && (table = busy_table.top())->n_end_time == cur_time;)
        {
          busy_table.pop();
          if(table->vip == 1)
            free_vip_table.push(table);
          else
            free_table.push(table);
        }

      // update wait queue
      // for vip
      for(; !wait_queue_vip.empty() && !free_vip_table.empty();)
        {
          player = wait_queue_vip.front();
          wait_queue_vip.pop();

          table = free_vip_table.top();
          free_vip_table.pop();

          assignTable(player, table, cur_time);
          result.push_back(player);
          busy_table.push(table);
        }

      // for non-vip
      for(; ;)
        {
          // Choose a player
          player = NULL;
          if(!wait_queue.empty())
            player = wait_queue.front();

          if(!wait_queue_vip.empty())
            {
              if(player == NULL)
                player = wait_queue_vip.front();
              else if(player->n_arrive_time > wait_queue_vip.front()->n_arrive_time)
                player = wait_queue_vip.front();
            }

          if(player == NULL) // no player
            break;

          // choose a table
          table = NULL;
          if(!free_table.empty())
            table = free_table.top();

          if(!free_vip_table.empty())
            {
              if(table == NULL)
                table = free_vip_table.top();
              else if(table->id > free_vip_table.top()->id)
                table = free_vip_table.top();
            }

          if(table == NULL) // no table
            break;

          if(player->vip == 1)
            wait_queue_vip.pop();
          else
            wait_queue.pop();

          if(table->vip == 1)
            free_vip_table.pop();
          else
            free_table.pop();

          assignTable(player, table, cur_time);
          result.push_back(player);
          busy_table.push(table);
        }
    }// for(cur_time)
}

void printResult(vector<Player*> const &result, Table table[], int ntable)
{
  int i;

  for(i = 0; i < result.size(); ++i)
    {
      Player *cur_player = result[i];

      cout << cur_player->arrive_time << " " ;
      // cout << toInt(cur_player->arrive_time) << " ";
      // cout << cur_player->play_time << " ";
      // cout << cur_player->vip << " ";
      cout << cur_player->serve_time << " ";
      cout << cur_player->wait_time << "\n";
    }
  for(i = 0; i < ntable; ++i)
    {
      cout << table[i].count;
      cout << ((i == ntable - 1) ? "\n" : " ");
    }
}

void process(Table table[], Player player[], int ntable, int nplayer)
{
  int i;
  Player **player_arr;

  table_type free_vip_table;
  table_type free_table;

  vector<Player*> result;

  player_arr = new Player*[nplayer];
  for(i = 0; i < nplayer; ++i)
    player_arr[i] = &player[i];

  // sort players according to the arrive time
  sort(player_arr, player_arr + nplayer, player_comp);

  // construct free vip table and free table
  for(i = 0; i < ntable; ++i)
    {
      if(table[i].vip == 1)
        free_vip_table.push(&table[i]);
      else
        free_table.push(&table[i]);
    }

  processUtil(player_arr, nplayer, free_table, free_vip_table, result);

  printResult(result, table, ntable);

  delete []player_arr;
}

int main()
{
#ifdef LINUX
  freopen("pat1026.in", "r", stdin);
#endif

  int i;
  int N; // the total number of pairs of players
  int K; // the number of tables
  int M; // the number of VIP tables
  cin >> N;

  for(i = 0; i < N; ++i)
    {
      cin >> g_player[i].arrive_time;
      g_player[i].n_arrive_time = toInt(g_player[i].arrive_time);

      cin >> g_player[i].play_time;
      if(g_player[i].play_time > 120)
        g_player[i].play_time = 120;

      cin >> g_player[i].vip;
    }
  cin >> K >> M;

  for(i = 0; i < K; ++i)
    {
      g_table[i].id = i + 1;
      g_table[i].vip = 0;
      g_table[i].end_time = "08:00:00";
      g_table[i].n_end_time = toInt(g_table[i].end_time);
      g_table[i].count = 0;
    }

  for(i = 0; i < M; ++i)
    {
      int num;
      cin >> num;
      g_table[num-1].vip = 1;
    }

  process(g_table, g_player, K, N);

  return(0);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值