145 · CSP 2022 提高级第一轮

CSP 2022 · 共 43 题 · 建议用时 60 分钟
开始整卷作答 按大题分页,翻页自动存草稿,做完统一交卷。
## 一、单项选择题(共 $15$ 题,每题 $2$ 分,共计 $30$ 分;每题有且仅有一个正确选项) 第 1–15 题 · 共 15 题
### (1) 第 16–21 题 · 共 6 题
### (2) 第 22–27 题 · 共 6 题
### (3) 第 28–33 题 · 共 6 题
## 三 完善程序(单选题,每小题 $3$ 分,共计 $30$ 分) 第 34–34 题 · 共 1 题
第 35–38 题 共 4 题
## 三 完善程序(单选题,每小题 $3$ 分,共计 $30$ 分) 第 39–39 题 · 共 1 题
**($2$)(容器分水)** 有两个容器,容器 $1$ 的容量为为 `a` 升,容器 $2$ 的容量为 `b` 升;同时允许下列的三种操作,分别为: 1. FILL(i):用水龙头将容器 $i(i \in {1,2})$ 灌满水; 2. DROP(i):将容器 i 的水倒进下水道; 3. POUR(i,j):将容器 i 的水倒进容器 j(完成此操作后,要么容器 j 被灌满,要么容器 i 被清空)。 求只使用上述的两个容器和三种操作,获得恰好 `c` 升水的最少操作数和操作序列。上述 `a`、`b`、`c` 均为不超过 $100$ 的正整数,且 `c≤max{a,b}`。 试补全程序。 ```cpp #include <bits/stdc++.h> using namespace std; const int N = 110; int f[N][N]; int ans; int a, b, c; int init; int dfs(int x, int y) { if (f[x][y] != init) return f[x][y]; if (x == c || y == c) return f[x][y] = 0; f[x][y] = init - 1; f[x][y] = min(f[x][y], dfs(a, y) + 1); f[x][y] = min(f[x][y], dfs(x, b) + 1); f[x][y] = min(f[x][y], dfs(0, y) + 1); f[x][y] = min(f[x][y], dfs(x, 0) + 1); int t = min(a - x, y); f[x][y] = min(f[x][y], ①); t = min(x, b - y); f[x][y] = min(f[x][y], ②); return f[x][y]; } void go(int x, int y) { if (③) return; if (f[x][y] == dfs(a, y) + 1) { cout << "FILL(1)" << endl; go(a, y); } else if (f[x][y] == dfs(x, b) + 1) { cout << "FILL(2)" << endl; go(x, b); } else if (f[x][y] == dfs(0, y) + 1) { cout << "DROP(1)" << endl; go (0, y); } else if (f[x][y] == dfs(x, 0) + 1) { cout << "DROP(2)" << endl; go(x, 0); } else { int t = min(a - x, y); if(f[x][y] == ④) { cout << "POUR(2,1)" << endl; go(x + t, y - t); } else { t = min(x, b - y); if (f[x][y] == ⑤) { cout << "POUR(1,2)" << endl; go(x - t, y + t); } else assert(0); } } } int main() { cin >> a >> b >> c; ans = 1 << 30; memset(f, 127, sizeof f); init = **f; if ((ans = dfs (0, 0)) == init - 1) cout << "impossible"; else { cout << ans << endl; go (0, 0); } } ``` 第 40–41 题 · 共 2 题
## 三 完善程序(单选题,每小题 $3$ 分,共计 $30$ 分) 第 42–42 题 · 共 1 题
第 43 题 共 1 题
展开逐题清单(单独练某一道)
● 绿=已通过 ● 橙=做过没全对 ● 灰=没做过
## 一、单项选择题(共 $15$ 题,每题 $2$ 分,共计 $30$ 分;每题有且仅有一个正确选项)
1. [CSP2022 提高级] 第 1 题 2. [CSP2022 提高级] 第 2 题 3. [CSP2022 提高级] 第 3 题 4. [CSP2022 提高级] 第 4 题 5. [CSP2022 提高级] 第 5 题 6. [CSP2022 提高级] 第 6 题 7. [CSP2022 提高级] 第 7 题 8. [CSP2022 提高级] 第 8 题 9. [CSP2022 提高级] 第 9 题 10. [CSP2022 提高级] 第 10 题 11. [CSP2022 提高级] 第 11 题 12. [CSP2022 提高级] 第 12 题 13. [CSP2022 提高级] 第 13 题 14. [CSP2022 提高级] 第 14 题 15. [CSP2022 提高级] 第 15 题
### (1)
16. [CSP2022 提高级] 第 16 题 17. [CSP2022 提高级] 第 17 题 18. [CSP2022 提高级] 第 18 题 19. [CSP2022 提高级] 第 19 题 20. [CSP2022 提高级] 第 20 题 21. [CSP2022 提高级] 第 21 题
### (2)
22. [CSP2022 提高级] 第 22 题 23. [CSP2022 提高级] 第 23 题 24. [CSP2022 提高级] 第 24 题 25. [CSP2022 提高级] 第 25 题 26. [CSP2022 提高级] 第 26 题 27. [CSP2022 提高级] 第 27 题
### (3)
28. [CSP2022 提高级] 第 28 题 29. [CSP2022 提高级] 第 29 题 30. [CSP2022 提高级] 第 30 题 31. [CSP2022 提高级] 第 31 题 32. [CSP2022 提高级] 第 32 题 33. [CSP2022 提高级] 第 33 题
## 三 完善程序(单选题,每小题 $3$ 分,共计 $30$ 分)
34. [CSP2022 提高级] 第 34 题 35. 题目 1166 不存在 36. 题目 1167 不存在 37. 题目 1168 不存在 38. 题目 1169 不存在
## 三 完善程序(单选题,每小题 $3$ 分,共计 $30$ 分)
39. [CSP2022 提高级] 第 39 题
**($2$)(容器分水)** 有两个容器,容器 $1$ 的容量为为 `a` 升,容器 $2$ 的容量为 `b` 升;同时允许下列的三种操作,分别为: 1. FILL(i):用水龙头将容器 $i(i \in {1,2})$ 灌满水; 2. DROP(i):将容器 i 的水倒进下水道; 3. POUR(i,j):将容器 i 的水倒进容器 j(完成此操作后,要么容器 j 被灌满,要么容器 i 被清空)。 求只使用上述的两个容器和三种操作,获得恰好 `c` 升水的最少操作数和操作序列。上述 `a`、`b`、`c` 均为不超过 $100$ 的正整数,且 `c≤max{a,b}`。 试补全程序。 ```cpp #include <bits/stdc++.h> using namespace std; const int N = 110; int f[N][N]; int ans; int a, b, c; int init; int dfs(int x, int y) { if (f[x][y] != init) return f[x][y]; if (x == c || y == c) return f[x][y] = 0; f[x][y] = init - 1; f[x][y] = min(f[x][y], dfs(a, y) + 1); f[x][y] = min(f[x][y], dfs(x, b) + 1); f[x][y] = min(f[x][y], dfs(0, y) + 1); f[x][y] = min(f[x][y], dfs(x, 0) + 1); int t = min(a - x, y); f[x][y] = min(f[x][y], ①); t = min(x, b - y); f[x][y] = min(f[x][y], ②); return f[x][y]; } void go(int x, int y) { if (③) return; if (f[x][y] == dfs(a, y) + 1) { cout << "FILL(1)" << endl; go(a, y); } else if (f[x][y] == dfs(x, b) + 1) { cout << "FILL(2)" << endl; go(x, b); } else if (f[x][y] == dfs(0, y) + 1) { cout << "DROP(1)" << endl; go (0, y); } else if (f[x][y] == dfs(x, 0) + 1) { cout << "DROP(2)" << endl; go(x, 0); } else { int t = min(a - x, y); if(f[x][y] == ④) { cout << "POUR(2,1)" << endl; go(x + t, y - t); } else { t = min(x, b - y); if (f[x][y] == ⑤) { cout << "POUR(1,2)" << endl; go(x - t, y + t); } else assert(0); } } } int main() { cin >> a >> b >> c; ans = 1 << 30; memset(f, 127, sizeof f); init = **f; if ((ans = dfs (0, 0)) == init - 1) cout << "impossible"; else { cout << ans << endl; go (0, 0); } } ```
40. [CSP2022 提高级] 第 40 题 41. [CSP2022 提高级] 第 41 题
## 三 完善程序(单选题,每小题 $3$ 分,共计 $30$ 分)
42. [CSP2022 提高级] 第 42 题 43. 题目 1174 不存在