- 智程星周赛
【ZCX-005-DIV3】智程星周赛005(入门组)题解
- @ 2026-4-21 22:30:56
题解思路
老师每次都会优先点 行号最大 的同学,也就是先点后面的行,再点前面的行。
因此对于小智:
- 第
x行下面所有同学,一定都会在他之前被点到; - 第
x行这一行中,点名顺序是随机的。
设:
below表示第x行下面所有学生人数;cnt表示第x行这一行的学生总人数。
那么:
- 小智最早可能在本行第一个被点到,所以答案是
below + 1; - 小智最晚可能在本行最后一个被点到,所以答案是
below + cnt。
参考代码(C++)
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005;
int a[MAXN][MAXN];
int main() {
int n, m, x, y;
cin >> n >> m >> x >> y;
// 读入教室情况
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
int below = 0;
// 统计第 x 行下面的所有学生人数
for (int i = x + 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
below += a[i][j];
}
}
int cnt = 0;
// 统计第 x 行这一行的学生总人数
for (int j = 1; j <= m; j++) {
cnt += a[x][j];
}
// 最早:本行第一个被点
// 最晚:本行最后一个被点
cout << below + 1 << " " << below + cnt;
return 0;
}
题意分析
给定一个只包含英文字母和 . 的字符串,按顺序执行两步操作:
- 对所有不是首字符的大写字母,如果它前一个字符不是
.,就在它前面插入一个.;最后如果字符串末尾不是.,还要在末尾补一个.。 - 对首字母和所有
.后面的字母,如果它是小写字母,就改成大写字母。
输出最终处理后的字符串。
解题思路
直接按照题意模拟即可。
先读入字符串 s。
第一步:处理首字母
如果首字母是小写字母,就先把它变成大写,然后直接输出。
第二步:从左到右扫描剩余字符
对于每个位置 i:
- 如果
s[i]是大写字母,并且前一个字符s[i-1]不是.,那么根据题意,需要在它前面插入一个.,所以先输出.。 - 如果
s[i]是小写字母,并且前一个字符s[i-1]是.,说明它处在句号后面,需要变成大写。 - 然后输出当前字符。
最后,如果当前字符已经是原串最后一个字符,并且它不是 .,就在末尾补输出一个 .。
为什么这样做是对的
题目要求的操作本质上只和 当前字符 以及它在 原串中的前一个字符 有关,因此我们不需要真的在字符串里插入字符,只要一边扫描一边输出最终结果即可。
这样做能完整实现:
- 大写字母前补
. - 首字母大写
.后字母大写- 末尾补
.
因此是正确的。
参考代码(带简要注释)
#include<bits/stdc++.h>
#define int long long
using namespace std;
signed main() {
string s;
cin >> s;
// 首字母如果是小写,改成大写
if (s[0] >= 'a' && s[0] <= 'z') {
s[0] -= 32;
}
// 先输出首字符
cout << s[0];
// 从第二个字符开始依次处理
for (int i = 1; i < s.size(); i++) {
// 如果当前字符是大写字母,且前面不是 '.'
// 则需要在它前面插入一个 '.'
if (s[i] >= 'A' && s[i] <= 'Z' && s[i - 1] != '.') {
cout << '.';
}
// 如果当前字符是小写字母,且前面是 '.'
// 则需要把它变成大写
else if (s[i] >= 'a' && s[i] <= 'z' && s[i - 1] == '.') {
s[i] -= 32;
}
// 输出当前字符
cout << s[i];
// 如果已经到最后一个字符,且它不是 '.'
// 需要在末尾补一个 '.'
if (i + 1 == s.size() && s[i] != '.') {
cout << '.';
}
}
return 0;
}
0 条评论
目前还没有评论...