solution-b3819

· · 题解

Source & Knowledge

2023 年 08 月语言月赛,由洛谷网校入门计划/基础计划提供。

本题考察字符串处理。

文字题解

题意简述

给出一份 n 个人的名单,要求将 m 个人从名单中删去,再加入 l 个人。按字典序输出最终的名单。

解析

90 分算法

n, m, l \leq 100 时,可以用一个大小为 200string 数组存储这个名单:string s[201];

首先读入名单上初始 n 个人名:

for (int i = 1; i <= n; ++i) cin >> s[i];

然后读入 m 个要被删去的人名。枚举名单上每一个人直到找到对应的人,然后将之置为空串,表示删去:

for (int i = 1; i <= m; ++i) {
  string t;
  cin >> t;
  for (int j = 1; j <= n; ++j) if (s[j] == t) {
    s[j] = "";
  }
}

最后读入 l 个新增的人名:

for (int i = n + 1; i <= n + l; ++i) cin >> s[i];

为了将它们从小到大排序,需要使用 sort(s + 1, s + 1 + n + l) 来把这些字符串排序。如果不会使用 sort,也可以自己写一个冒泡排序。

最后,按从小到大的顺序输出这些字符串就可以了。需要注意的是,被置为空串的字符串不应该输出:

for (int i = 1; i <= n + l; ++i) if (s[i] != "") cout << s[i] << '\n';

100 分算法

可以使用 STL 中的 set 完成上述操作。

set 是一个容器,它可以支持向容器中插入一个元素、删除一个元素和按从小到大的顺序输出。声明方式是:set<string> s;

读入初始名单只需要使用 setinsert 方法把字符串插入 set 中:

for (int i = 1; i <= n; ++i) {
  string t;
  s.insert(t);
}

删除字符串只需要使用 seterase 方法:

for (int i = 1; i <= n; ++i) {
  string t;
  s.erase(t);
}

最后再按与读入初始名单类似的方法读入剩下的 l 个名字即可。

在输出部分,因为 set 中元素本身自动按从小到大排序,所以只需要使用 range for 语法,直接遍历 set 输出即可。注意这一语法需要使用到 c++11 及以上编译标准。可以查看视频题解了解如何在编译时开启 C++11 及以上标准。

for (auto t : s) cout << t << '\n';

视频题解

等待上传。