语法周赛 Round 10 题解
2024年12月25日大约 5 分钟
A.骰子比大小
分析
- 难度:基础条件条件判断
- 子任务 1(30 分):保证了两个人的组合类型都是“三个一样的点数”,只需要比较
与 的大小关系就好。 - 子任务 2(30 分):保证了类型一致,只需要比较
与 的大小关系就好。 - 子任务 3(40 分):按照题意比较即可,如果直接列举所有情况显然要写很多
if
。可以考虑先整理一下每个人的点数,然后分别判断好两个人的类型,最后比较起来就很简单了。详细可以参考下面的代码。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
int x, y, z, typA, sumA;
int a, b, c, typB, sumB;
cin >> x >> y >> z;
cin >> a >> b >> c;
// 先排个序方便后续操作
if (x > y)
swap(x, y);
if (x > z)
swap(x, z);
if (y > z)
swap(y, z);
if (a > b)
swap(a, b);
if (a > c)
swap(a, c);
if (b > c)
swap(b, c);
// 判断类型与计算数字和
sumA = x + y + z;
if (x == y && y == z)
typA = 1;
else if (x + 1 == y && y + 1 == z)
typA = 2;
else if (x == y || y == z || x == z)
typA = 3;
else
typA = 4;
sumB = a + b + c;
if (a == b && b == c)
typB = 1;
else if (a + 1 == b && b + 1 == c)
typB = 2;
else if (a == b || b == c || a == c)
typB = 3;
else
typB = 4;
// 判断胜负
if (typA == 1 && a == 2 && b == 3 && c == 5)
cout << "B"; // 特殊情况 1
else if (typB == 1 && x == 2 && y == 3 && z == 5)
cout << "A"; // 特殊情况 2
else if (typA == typB && sumA == sumB)
cout << "B"; // 平局
else if (typA < typB || (typA == typB && sumA > sumB))
cout << "A"; // A 常规获胜规则
else
cout << "B"; // A 没获胜的情况
return 0;
}
B.停车场收费
分析
- 难度:基础循环模拟,涉及一点点数学技巧
- 子任务 1(30 分):保证了是同一天,只需要先判断是否为周末,然后一个小时一个小时模拟就好。
- 子任务 2(30 分):保证了第一天和最后一天都包括了完整的一天,因此不用管小时了,每个非周末的天都需要收费
元,但是如果一天天模拟显然会超时,容易发现每七天的收费一样,所以可以先算出一共多少天,有几个完整周和几天零散的。 - 子任务 3(40 分):先把中间的完整周用数学方法快速计算,然后前后一个小时一个小时模拟就好。这里细节比较多,可以参考我的代码,没必要写得那么精细,可以提前预留多一些天来暴力枚举,就不需要想那么多了。
考虑到第二题可能会花费一些同学比较多的时间,因此后两题稍微出得简单了一点。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
signed main()
{
long long x, y, l, s, r, e;
cin >> x >> y >> l >> s >> r >> e;
long long weekPri = 5 * (2 * x + 11 * y); // 完整一周的价格
long long ans = 0;
long long len = r - l + 1; // 总天数
if (len >= 100)
{
long long partA = 14; // 留 14 天容错
long long partB = len - partA;
ans += partB / 7 * weekPri; // partB中的完整周快速计算总价格
partA += partB % 7; // partA为中间剩余的天数
r = l + partA - 1; // 更新新的右端点天数
}
long long day = l;
long long hour = s;
while (day < r || hour < e)
{
// 计算当前小时的收费
if (day % 7 != 6 && day % 7 != 0) // 非周末
{
if (17 <= hour && hour < 19)
{
ans += x;
//cout << day << " " << hour << " +" << x << " = " << ans << "\n";
}
else if (8 <= hour && hour < 21)
{
ans += y;
//cout << day << " " << hour << " +" << y << " = " << ans << "\n";
}
}
hour++;
if (hour == 24)
{
day++;
hour = 1;
}
}
cout << ans;
return 0;
}
C.单词排排序
分析
- 难度:简单字符串中的字符统计+排序
- 子任务 1(30 分):统计每个小写英文字母的出现次数,然后按照出现次数排序输出即可。
- 子任务 2(30 分):因为不包含标点符号。所以只需要统计英文字母和数字即可,需要注意空格在这题不属于标点符号,所以子任务 2 就需要使用
getline
来输入了。 - 子任务 3(40 分):那些特殊的标点符号写起来比较麻烦,但实际上可以直接利用每个字符对应的整数值,也就是字符的 ascii 码就好,直接
cnt[s[i]]++;
来统计就很方便了。这里我采用了更暴力的直接把每个字符和对应的次数构建了一个结构体,然后进行结构体排序。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
struct C
{
char c;
int cnt;
};
int tot = 0;
C a[256];
bool cmp(C a, C b)
{
if (a.cnt != b.cnt)
return a.cnt > b.cnt;
return a.c < b.c;
}
int main()
{
string s;
getline(cin, s);
int cnt[300] = {};
for (int i = 0; i < s.size(); i++)
cnt[s[i]]++;
for (int i = 0; i < 256; i++)
if (cnt[i] > 0 && (char)i != ' ')
{
tot++;
a[tot] = (C){(char)i, cnt[i]};
}
sort(a + 1, a + tot + 1, cmp);
for (int i = 1; i <= tot; i++)
{
cout << a[i].c;
//cout << "(" << a[i].cnt << ")";
}
//cout << "#";
return 0;
}
// I have a apple, I have a pen, Uh, applepen!
D.登记排行榜
分析
- 难度:数组、字符串、排序
- 子任务 1(30 分):保证了只有女生,直接输出
数组即可。 - 子任务 2(30 分):保证了过线顺序就是编号顺序,检查每个人的性别,先一个个输出男生,然后一个个输出女生即可。
- 子任务 3(40 分):有多种做法,可以直接枚举两次
数组,第一次输出所有男生,第二次输出所有女生即可。我这里直接统计了每个人的排名,然后把男生女生放到了不同的数组,然后对两个数组种存储的编号按照排名为依据排序。
满分参考代码
#include <bits/stdc++.h>
using namespace std;
int rnk[1005];
int boyTot = 0, boy[1005];
int girlTot = 0, girl[1005];
bool cmp(int a, int b)
{
return rnk[a] < rnk[b];
}
int main()
{
int n;
string s;
int a[1005];
cin >> n;
cin >> s;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
rnk[a[i]] = i;
if (s[i - 1] == 'm')
boy[++boyTot] = i;
else
girl[++girlTot] = i;
}
sort(boy + 1, boy + boyTot + 1, cmp);
sort(girl + 1, girl + girlTot + 1, cmp);
for (int i = 1; i <= boyTot; i++)
cout << boy[i] << " ";
cout << "\n";
for (int i = 1; i <= girlTot; i++)
cout << girl[i] << " ";
cout << "\n";
return 0;
}