1026. Table Tennis (30)

来源:互联网 发布:java中迭代器的使用 编辑:程序博客网 时间:2024/04/28 23:04

又是复杂模拟题。。。再度奉上大神代码

#include<cstdio>  #include<string>  #include<cstring>  #include<vector>  #include<iostream>  #include<queue>  #include<map>  #include<algorithm>  using namespace std;  typedef long long LL;  const int INF = 0x7FFFFFFF;  const int maxn = 1e5 + 10;  int n, f[maxn], t[maxn], x, y, z, m, u, vis[maxn], cnt[maxn];    struct point  {      int x, y, f;      bool operator<(const point &a)const      {          return x < a.x;      }  }a[maxn];    void putout(int x)  {      printf("%02d:%02d:%02d ", x / 3600, x / 60 % 60, x % 60);  }    void putmin(int x)  {      printf("%d\n", x / 60 + (x % 60 < 30 ? 0 : 1));//满30秒进1分  }    int main()  {      scanf("%d", &n);      for (int i = 0; i < n; i++)      {          scanf("%d:%d:%d", &x, &y, &z);          a[i].x = x * 3600 + y * 60 + z;          scanf("%d%d", &x, &a[i].f);          a[i].y = min(x * 60, 7200);//最多不超过2小时      }      sort(a, a + n);      scanf("%d%d", &m, &u);      while (u--) scanf("%d", &x), f[x] = 1;      for (int i = 1; i <= m; i++) t[i] = 8 * 3600;      for (int i = 0; i < n; i++)      if (!vis[i])      {          int now = 1;          for (int j = 1; j <= m; j++) if (t[now] > t[j]) now = j;//找出最早空出的桌子          if (max(t[now], a[i].x) >= 21 * 3600) break;//超过21点跳出          if (t[now] <= a[i].x)//这意味着现在不用排队          {              int vip = -1;//如果这个人是vip那么会选择能用的vip的桌子中最小的              for (int j = m; j >= 1; j--)              {                  if (t[j] <= a[i].x) now = j;                  if (t[j] <= a[i].x&&f[j]) vip = j;              }              if (a[i].f&&vip != -1) now = vip; //如果这个人是vip且有vip的桌子能用              cnt[now]++;              putout(a[i].x); putout(a[i].x);              printf("0\n"); t[now] = a[i].x + a[i].y;          }          else//这意味着现在有人在排队          {              /*这部分有个问题             如果有人在排队,并且同时空出了一张非vip桌子和一张vip桌子,             如果标号小的不是vip,标号大的是vip,那么先处理哪个呢,题目没有明确的指出             经过我的测试,也没有这样的数据,所以可以忽略。              int vip = -1;   //如果有vip桌子同时也可用             for (int j = m; j >= 1; j--)             {                 if (t[j] == t[now] && f[j]) vip = j;             }             if (vip != -1)//先选择处理vip桌子             {                 int flag = 0;                 for (int j = i; j < n&&a[j].x <= t[vip]; j++)                 {                     if (a[j].f&&!vis[j])                     {                         vis[j] = 1;                         putout(a[j].x); putout(t[vip]);                         putmin(t[vip] - a[j].x);                         t[vip] = t[vip] + a[j].y;                         flag = 1; break;                     }                 }                 if (flag) { cnt[vip]++; i--; continue; }             }             */              cnt[now]++;              if (f[now])     //如果是vip的桌子              {                  int flag = 0;                  for (int j = i; j < n&&a[j].x <= t[now]; j++)//找到是否有vip在等待                  {                      if (a[j].f&&!vis[j])                      {                          vis[j] = 1;                          putout(a[j].x); putout(t[now]);                          putmin(t[now] - a[j].x);                          t[now] = t[now] + a[j].y;                          flag = 1; break;                      }                  }                  if (flag) i--;                  else//如果没有,那么第一个人用了                  {                      putout(a[i].x); putout(t[now]);                      putmin(t[now] - a[i].x);                      t[now] = t[now] + a[i].y;                  }              }              else//非vip桌子,直接用              {                  putout(a[i].x); putout(t[now]);                  putmin(t[now] - a[i].x);                  t[now] = t[now] + a[i].y;              }          }      }      for (int i = 1; i <= m; i++) printf("%d%s", cnt[i], i == m ? "\n" : " ");      return 0;  }  


0 0