挖土机周赛 Round 32(语法场)题解
2024年12月24日大约 3 分钟
这场为了和 CSP-J 2024 标题一致,第三题没有特别严谨地做纯字符串题。
33DAI 的扑克牌
题解
作为语法周赛的第一题,不超纲的话那就下面的 if-else
处理最方便。
更优雅的代码可以定义两个字符串 "A23456789TJQK"
和 "DCHS"
,然后用循环找到下标来对应到具体的数字。
参考代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
char D1, D2, K1, K2;
cin >> D1 >> D2 >> K1 >> K2;
int d1, d2, k1, k2;
if (D1 == 'D')
d1 = 4;
else if (D1 == 'C')
d1 = 3;
else if (D1 == 'H')
d1 = 2;
else if (D1 == 'S')
d1 = 1;
if (D2 == 'A')
d2 = 1;
else if (D2 == 'T')
d2 = 10;
else if (D2 == 'J')
d2 = 11;
else if (D2 == 'Q')
d2 = 12;
else if (D2 == 'K')
d2 = 13;
else
d2 = D2 - '0';
if (K1 == 'D')
k1 = 4;
else if (K1 == 'C')
k1 = 3;
else if (K1 == 'H')
k1 = 2;
else if (K1 == 'S')
k1 = 1;
if (K2 == 'A')
k2 = 1;
else if (K2 == 'T')
k2 = 10;
else if (K2 == 'J')
k2 = 11;
else if (K2 == 'Q')
k2 = 12;
else if (K2 == 'K')
k2 = 13;
else
k2 = K2 - '0';
if (d1 * 14 + d2 > k1 * 14 + k2)
cout << "33DAI";
else
cout << "Kitten";
return 0;
}
33DAI 的地图探险
题解
首先因为
大家可以想一下,假如
显然此时不能模拟了,但很容易发现没有障碍物的时候整个路径分为两步
- 走到边界:可以通过位置和方向
算出走到了边界的什么位置。 - 在边界上绕圈:可以算算多少步回到起始位置,显然接下来对这个步数取余,即可找到对应位置了。
参考代码
#include <bits/stdc++.h>
using namespace std;
int n, m, k;
int x, y, d;
int main()
{
cin >> n >> m >> k;
cin >> x >> y >> d;
for (int i = 1; i <= k; i++)
{
int xx = x, yy = y;
if (d == 0)
yy++;
if (d == 1)
xx++;
if (d == 2)
yy--;
if (d == 3)
xx--;
if (1 <= xx && xx <= n && 1 <= yy && yy <= m)
x = xx, y = yy;
else
d = (d + 1) % 4;
}
cout << x << " " << y << "\n";
return 0;
}
33DAI 的小木棍
题解
对比 CSP-J 2024 的 T3,这题没要求恰好,并且只能用一种数字,所以非常简单。
先算算用不同的数字分别需要至少几位才够,然后找位数最少的,位数一样就找数字最小的即可。
参考代码
#include <bits/stdc++.h>
using namespace std;
int num[] = {6, 2, 5, 5, 4, 5, 6, 3, 7, 6};
int n;
int a[10];
int main()
{
cin >> n;
for (int i = 1; i <= 9; i++)
a[i] = (n + (num[i] - 1)) / num[i];
int ans = 1;
for (int i = 2; i <= 9; i++)
if (a[i] < a[ans])
ans = i;
for (int i = 1; i <= a[ans]; i++)
cout << ans;
return 0;
}
33DAI 的接龙
题解
首先对于
有多同学一看到这个就以为要上并查集了,但要注意这实际上是单向边,所以不能直接来并查集。并查集有可能
有同学可能会想到建个图然后 dfs,但显然作为语法周赛是朝纲的。
实际上我们很容易用 vis[i]
记录能不能变为 i
,然后写出下面这段代码,
for (int j = 1; j <= n; j++)
if (vis[a[j]])
vis[b[j]] = true;
但容易发现,做一次肯定是不够的,那多做几次就好了。这个次数如果不想推可以给一个不超时的大数就好。实际上可以保证
参考代码
#include <bits/stdc++.h>
using namespace std;
int n, s, e;
int a[15], b[15];
bool vis[15];
int main()
{
cin >> n >> s >> e;
for (int i = 1; i <= n; i++)
cin >> a[i] >> b[i];
vis[s] = true;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (vis[a[j]])
vis[b[j]] = true;
if (vis[e])
cout << "Yes\n";
else
cout << "No\n";
return 0;
}