[语言月赛202304E] 你的牌太多
一扶苏一
·
·
题解
[语言月赛202304E] 你的牌太多了 题解
Source & Knowledge
2023 年 4 月语言月赛,由洛谷网校入门计划/基础计划提供。
本题考查一维数组的应用。
文字题解
题目大意
扶苏和小 F 玩牌,初始时每人都有 n 张牌,每次扶苏先出牌,小 F 会在自身手牌中选择花色与扶苏的牌相同且点数大于扶苏出牌的牌里点数最小的牌,然后打出。
求最终小 F 手里剩了几张牌。
### 解析
依照题意模拟即可。
首先使用四个数组 `f1`,`p1`,`f2`,`p2` 来存储双方的手牌信息。为了能知道每张牌是否被打出,还需呀一个 `vis` 数组表示每张牌是否被使用过了。
每次读入扶苏打出的手牌编号 $x$,然后用一个变量 $pos$ 表示本轮小 F 打出的手牌编号。初始时 $pos = 0$ 表示没有找到打出的牌。
枚举一遍小 F 所有的手牌,对一个还未打出的牌,如果它的花色和扶苏的牌相同且点数比扶苏的牌大,则比较这个牌的点数和 $pos$ 号牌的点数,尝试更新 $pos$。注意当 $pos$ 位 $0$ 时无需比较,直接更新。
```cpp
for (int x, i = 1; i <= n; ++i) {
cin >> x; --x;
int pos = 0;
for (int i = 1; i <= n; ++i) if (!use[i]) {
if (f2[i] == f1[x] && p2[i] > p1[x]) {
if (pos == 0) pos = i;
else if (p2[pos] > p2[i]) pos = i;
}
}
if (pos != 0) use[pos] = 1;
}
```
最后,统计 use 数组里为 $0$ 的数字数量,就是没有打出的牌。这一步可以使用一个循环完成:
```cpp
int ans = 0;
for (int i = 1; i <= n; ++i) if (!use[i]) ++ans;
cout << ans << '\n';
```
也可以使用 `algorithm` 头文件中的函数 `count(begin, end, val)` 完成。它的作用是查询 $[begin, end)$ 区间内等于 $val$ 的数字个数。
```cpp
cout << count(use + 1, use + 1 + n, 0);
```
## 视频题解
**完整代码请在视频题解中查看**。
