题解 B4087

· · 题解

[语言月赛 202412] 吃饭大赛总决赛 题解

Source & Knowledge

本题来源于 2024 年 12 月的语言月赛,主要考察结构体、数组以及逻辑判断的使用。

文字题解

【结构体定义】
我们采用这样一个结构体来维护一支队伍的信息

struct Team {
  string name;
  string number[3];

  Team(string x, string y, string z, string w) {
    name = x;
    number[0] = y;
    number[1] = z;
    number[2] = w;
  }

  Team() {}
}

【数据读入】
我们用 Team rank[i][j] 这个数据表示第 j 场比赛的 第 i 名,根据题意读入信息并存储到数组里:

std::cin >> n >> m >> t >> k;
for (int i = 1; i <= n; ++i) {
  std::string a, b, c, d;
  int x, y;
  std::cin >> a >> b >> c >> d >> x >> y;
  rank[y][x] = Team(a, b, c, d);
}

【数据存储】
为了判定每个人是否已经晋级 ec,我们用一个数组 string ecNumber[5000] 来存储所有当前已经晋级 ec 的队员姓名,int ecNumberCnt 表示当前晋级的人员数量;Team ecTeam[5000] 来存储当前所有晋级 ec 的队伍信息,int ecCnt 来存储当前晋级的队伍数量。

接下来,按题意先枚举排名,再枚举比赛编号,判断每支队伍是否可以晋级

for (int i = 1; i <= t; ++i) {
  for (int j = 1; j <= m; ++j) if (rank[i][j].name.size() != 0) { // name 的长度不是 0 说明这里有队伍信息
    if (ecCnt >= k) break;
    bool ok = true;
    for (int u = 0; u < 3; ++u) {
      string x = rank[i][j].number[u];
      for (int t = 0; t < ecNumberCnt; ++t) if (x == ecNumber[t]) { // 遍历晋级人员名单,检查 x 是否已晋级
        ok = false;
      }
    }
    if (!ok) continue; // 有人员晋级则该队伍无法再晋级
    ecTeam[ecCnt++] = rank[i][j];
    for (int u = 0; u < 3; ++u) {
      string x = rank[i][j].number[u];
      ecNumber[ecNumberCnt++] = x;
    }
  }
}

最后,ecCnt 就是所有晋级的队伍,按规定输出即可。