考试题倒不是有多难,就是需要注意的细节有很多。我的总分是 218,二等奖擦边过~算是运气比较好吧。
考试的时候手机(第二机位)没电关机了,但是老师没管哈哈哈。。。
点击下面的题目标题跳转到对应题目链接~🫢
L1-1 编程解决一切
考察:简单输出
解题思路
语言选择 Python → 鼠标放到输出样例最右端一键赋值 → 提交(5s 解决)
代码
print('Problem? The Solution: Programming.')
L1-2 再进去几个人
考察:简单输入输出
解题思路
这道题代码很少,就是读题可能稍微花点时间,但也能 2 分钟内解决。
代码
a, b = map(int, input().split())
print(b - a)
L1-3 帮助色盲
考察:模拟
解题思路
按照题目中的要求一点一点写就行。
代码
a, b = map(int, input().split())
if a <= 1:
if b: print('-')
else: print('dudu' if a else 'biii')
else: print('-')
print('move' if a == 1 else 'stop')
L1-4 四项全能
考察:简单数学
解题思路
假设所有人会 m - 1 种技能点,多出的技能点的数量就是要求的人数。
注意技能点总数有可能不足 n * (m - 1),这时输出 0
代码
n, m = map(int, input().split())
print(max(0, sum(map(int, input().split())) - n * (m - 1)))
L1-5 别再来这么多猫娘了
考察:简单字符串查找
解题思路
注意题目中的关键信息:“从左到右处理文本,违禁词则按照输入顺序依次处理;对于有重叠的情况,无论计数还是替换,查找完成后从违禁词末尾继续处理。”
然后模拟上述操作即可。但是我只能得 10 分,不知道为啥。
代码
n = int(input())
banned = [input() for _ in range(n)]
k, c = int(input()), 0
s = input()
i, res = 0, ''
while i < len(s):
for b in banned:
if s[i:i + len(b)] == b:
c += 1
i += len(b)
res += '<censored>'
break
else:
res += s[i]
i += 1
print(res if c < k else f'{c}\nHe Xie Ni Quan jia!')
L1-6 兰州牛肉面
考察:语法
解题思路
用一个 cnt 数组保存每种牛肉面的购买次数,用 total 累加总销售额。
代码
cin = lambda t=int: list(map(t, input().split()))
n = int(input())
prices = cin(float)
cnt, total = [0] * n, 0
while True:
t, num = cin()
if not t: break
cnt[t - 1] += num
total += prices[t - 1] * num
for c in cnt:
print(c)
print('%.2f' % total)
L1-7 整数的持续性
考察:模拟
解题思路
L1 一般对时间复杂度没有要求,所以直接模拟就行。
代码
a, b = map(int, input().split())
def calc(x):
res = 0
while len(str(x)) > 1:
t = 1
while x:
t *= x % 10
x //= 10
x = t
res += 1
return res
mx, ans = 0, []
for i in range(a, b + 1):
t = calc(i)
if t > mx: mx, ans = t, [i]
elif t == mx: ans.append(i)
print(mx)
print(' '.join(str(i) for i in ans))
L1-8 九宫格
考察:模拟、简单思维
解题思路
用三个数组保存每一行、每一列、每个九宫格中每个数的出现情况。如果1~9中有数字出现多次,或者出现范围外的数字,就把 flag 设为 false。
代码
for _ in range(int(input())):
m = [list(map(int, input().split())) for _ in range(9)]
r, c, v = [[[0] * 10 for _ in range(9)] for _ in range(3)]
flag = False
for i in range(9):
for j in range(9):
if m[i][j] <= 0 or m[i][j] > 9 or r[i][m[i][j]] or c[j][m[i][j]] or v[i // 3 * 3 + j // 3][m[i][j]]:
flag = True
break
r[i][m[i][j]] = c[j][m[i][j]] = v[i // 3 * 3 + j // 3][m[i][j]] = 1
if flag: break
print(0 if flag else 1)
L2-1 鱼与熊掌
考察:平衡树
解题思路
用 set 来记录每种商品的购买者。然后在多个集合中找交集即可。
注意为了不让最后一个点超时,要加一个小优化:遍历较小的集合。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m;
set<int> M[N];
int main() {
cin.tie(0) -> sync_with_stdio(false);
cin >> n >> m;
for (int i = 1, k; i <= n; i++) {
cin >> k;
while (k--) {
int x; cin >> x;
M[x].insert(i);
}
}
int q; cin >> q;
while (q--) {
int x, y, res = 0;
cin >> x >> y;
if (M[x].size() <= M[y].size())
for (int i : M[x])
res += M[y].count(i);
else
for (int i : M[y])
res += M[x].count(i);
cout << res << endl;
}
return 0;
}
L2-2 懂蛇语
考察:哈希表
解题思路
注意输入的单词中可能会有多个空格,开头也有可能有空格。
注意整行输入前要用 cin.ignore() 或者 getchar() 来忽视掉换行符。
用 C++ 的 stringstream 可以很好的处理这种输入。
代码
#include <bits/stdc++.h>
using namespace std;
unordered_map<string, vector<string>> mp;
string trans(string& line) {
string ans, t;
stringstream ss(line);
while (ss >> t)
ans += t[0];
return ans;
}
int main() {
int n, m;
cin >> n; cin.ignore();
while (n--) {
string line;
getline(cin, line);
mp[trans(line)].emplace_back(line);
}
for (auto& [k, v] : mp)
sort(v.begin(), v.end());
cin >> m; cin.ignore();
while (m--) {
string line;
getline(cin, line);
string res = trans(line);
if (mp.count(res)) {
int sz = mp[res].size();
for (int i = 0; i < sz; i++)
cout << mp[res][i] << "|\n"[i == sz - 1];
} else cout << line << endl;
}
return 0;
}
L2-3 满树的遍历
考察:树、DFS
解题思路
树的前序遍历没啥好说的。用一个变量保存每个节点的度,判断是不是满树。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, f[N], rt, k;
vector<int> e[N], pre;
bool dfs(int u) {
if (e[u].empty())
return true;
if (k != e[u].size())
return false;
k = max(k, (int)e[u].size());
for (int& v : e[u])
if (!dfs(v))
return false;
return true;
}
void preorder(int u) {
pre.emplace_back(u);
sort(e[u].begin(), e[u].end());
for (int& v : e[u])
preorder(v);
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> f[i];
if (!f[i]) rt = i;
e[f[i]].emplace_back(i);
}
k = e[rt].size();
bool res = dfs(rt);
cout << k << ' ' << (res ? "yes" : "no") << endl;
preorder(rt);
for (int i = 0; i < n; i++)
cout << pre[i] << " \n"[i == n - 1];
return 0;
}
L2-4 吉利矩阵
考察:回溯
解题思路
在一个二维矩阵内回溯,用 r 和 c 数组分别保存每一行、每一列列的总和,注意细节和边界情况即可。
代码
#include <bits/stdc++.h>
using namespace std;
int l, n, res, r[4], c[4];
void add(int i, int j, int x) {
r[i] += x;
c[j] += x;
}
void rm(int i, int j, int x) {
r[i] -= x;
c[j] -= x;
}
void dfs(int i, int j) {
if (i == n - 1 && j != n - 1) {
int x = l - c[j];
add(i, j, x);
if (r[i] <= l && c[i] <= l)
dfs(i, j + 1);
rm(i, j, x);
return;
}
if (j == n - 1 && i != n - 1) {
int x = l - r[i];
add(i, j, x);
if (r[i] <= l && c[i] <= l)
dfs(i + 1, 0);
rm(i, j, x);
return;
}
if (i == n - 1 && j == n - 1) {
res += r[i] == c[j];
return;
}
for (int x = 0; x <= l - max(r[i], c[j]); x++) {
add(i, j, x);
dfs(i, j + 1);
rm(i, j, x);
}
}
int main() {
cin >> l >> n;
dfs(0, 0);
cout << res;
return 0;
}
L3-1 夺宝大赛
考察:BFS
解题思路
用多个数组记录多个节点的遍历情况。但是最后一个点超时了,求大佬赐教!
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 105, nxt[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
int m, n, a[N][N], tx, ty;
bool vis[N * N / 2][N][N];
queue<tuple<int, int, int>> q;
vector<int> winner;
int main() {
cin >> m >> n;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++) {
cin >> a[i][j];
if (a[i][j] == 2)
tx = i, ty = j;
}
int k; cin >> k;
for (int i = 1; i <= k; i++) {
int x, y;
cin >> y >> x;
vis[i][x][y] = true;
q.push({x, y, i});
}
int t = 0;
while (q.size()) {
int sz = q.size();
while (sz--) {
auto [x, y, id] = q.front(); q.pop();
if (x == tx && y == ty) {
winner.emplace_back(id);
continue;
}
for (int i = 0; i < 4; i++) {
int nx = x + nxt[i][0], ny = y + nxt[i][1];
if (0 < nx && nx <= m && 0 < ny && ny <= n && a[nx][ny] && !vis[id][nx][ny]) {
vis[id][nx][ny] = true;
q.push({nx, ny, id});
}
}
}
if (winner.size()) {
if (winner.size() > 1) winner.clear();
else {
cout << winner[0] << ' ' << t;
return 0;
}
}
t++;
}
cout << "No winner.";
return 0;
}
最后
有什么问题欢迎在评论区讨论交流!