- 西中经开联校 - 第 10 场周赛
【题解】西中经开联校 - 第 10 场周赛
- @ 2025-3-31 10:22:52
偶数场周赛较难,奇数场周赛较易。
T1 时区转换
难度:简单条件判断,输入时有一些小技巧。
算法:数学,模拟。
子任务 ( 分):口算出答案后直接输出对应的结果即可。
子任务 ( 分):此时需要输入正确的时间,有同学可能会以为需要字符串处理,实际上可以考虑用五个字符,或者直接定义 int a, b; char c; 然后 cin >> a >> c >> b; 即可。在输入整数时,程序会读取直到非数字字符为止,前导 也不会影响正确的数值。然后用一个字符型变量吃掉中间的冒号再输入第二个整数即可。输入完成之后因为保证了时间不会跨越一天,直接输出 a - 15 和 b 即可,但要注意根据格式给出多余的 。
子任务 ( 分):有可能会跨越一天时,根据 a 的值确认是否要 + 24 就好。
参考代码:此处还是按照个人的习惯,对于时间类的问题转换为最小单位后在处理。显然在本题中,“转换为分钟”、“往前数 小时”、“转换回小时” 可以直接用 a -= 15; if (a < 0) a += 24; 代替。
C++ 代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a, b;
char c;
cin >> a >> c >> b;
// 转换为分钟
int t = a * 60 + b;
// 往前数 15 小时
t -= 15 * 60;
if (t < 0) t += 24 * 60;
// 转换回小时
a = t / 60;
b = t % 60;
// 按格式输出
if (a < 10)
cout << "0" << a;
else
cout << a;
cout << ":";
if (b < 10)
cout << "0" << b << endl;
else
cout << b << endl;
return 0;
}
T2 每数一位
难度:基础循环嵌套及数学找规律。
算法:数学,模拟。
子任务 ( 分):当 为一位数时,直接输入 之和即可。
子任务 ( 分):数据范围很小,直接用 暴力枚举 之内的每个整数,使用题目给出的“求数位和”的代码求出“一位数位和”然后求和即可。
子任务 ( 分):容易发现当数据范围很大时上面的思路会超时,可以考虑先打印出每个数的一位数位和看看规律,很容易发现就是 的循环,直接根据数学规律算出答案即可。注意要用 long long。
60 分参考代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n;
long long ans;
cin >> n;
ans = 0;
for (long long i = 1; i <= n; i ++ )
{
// 将 i 变为一位数
long long now = i;
while (now > 9)
{
long long num = 0; // 计算 now 的数位和
while (now > 0)
{
num += now % 10;
now /= 10;
}
now = num;
}
// 算入答案
ans += now;
// cout << i << ":" << now << endl;
}
cout << ans << endl;
return 0;
}
满分参考代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n;
cin >> n;
long long a = n / 9;
long long b = n % 9;
cout << (a * 45) + (1 + b) * b / 2 << endl;
return 0;
}
T3 数串质数
难度:简单字符串处理及质数判断。
算法:字符串处理,数学。
子任务 ( 分):此时数串只有三种可能性 10、1011、101112,根据题目描述容易发现答案都是 0。
子任务 ( 分):根据题目描述,容易发现 n 为 1∼12 时答案为 0,为 13 时答案为 1,为 14∼29 时答案都为 2,30∼33 时答案为 3。这题的 60 分就是一个条件判断的题目。
子任务 ( 分):通过加号把几个数组合成一个字符串后处理即可。也可以用整数的方式,(四位质数必然为一个数的十位开头或者一个数的个位开头,和后面的数字组合形成的)。
C++ 代码 1:
#include <bits/stdc++.h>
using namespace std;
int n;
string s;
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i <= n / i; i ++ )
if (n % i == 0)
return false;
return true;
}
int main()
{
cin >> n;
for (int i = 10; i <= n; i ++ )
{
s += (char)(i / 10 + '0');
s += (char)(i % 10 + '0');
}
//cout << s << "\n";
int cnt = 0;
for (int i = 0; i + 4 - 1 < s.size(); i ++ )
{
if (s[i] == '0') continue;
int now = (s[i] - '0') * 1000 +
(s[i + 1] - '0') * 100 +
(s[i + 2] - '0') * 10 +
(s[i + 3] - '0');
if (is_prime(now))
{
cnt ++ ;
//cout << now << "\n";
}
}
cout << cnt << endl;
return 0;
}
C++ 代码 2:
#include <bits/stdc++.h>
using namespace std;
int n, s;
bool is_prime(int n)
{
if (n < 2) return false;
for (int i = 2; i <= n / i; i ++ )
if (n % i == 0)
return false;
return true;
}
int main()
{
cin >> n;
for (int i = 10; i <= n - 1; i ++ )
{
int a = (i/10)*1000+(i%10)*100+((i+1)/10)*10+((i+1)%10)*1;
int b = (i%10)*1000+((i+1)/10)*100+((i+1)%10)*10+((i+2)/10)*1;
if (1000 <= a && a <= 9999 && is_prime(a)) s ++ ;
if (i + 2 <= n && 1000 <= b && b <= 9999 && is_prime(b)) s ++ ;
}
cout << s << endl;
return 0;
}
T4 四数转盘
难度:简单模拟。
算法:模拟。
子任务 ( 分):保证了两个字符串长度都为 ,又至少有一个 o,所以直接根据 op[0] 的值决定输出 B 还是 D 即可。
子任务 ( 分):保证了每个字符都要输出,直接专心模拟旋转即可。
子任务 ( 分):在 分的基础上,根据 的值决定是否输出即可。容易发现除了真的去模拟转盘旋转之外,如果把 ABCD 对应到 0123,左转右转就是 然后对 取余了。
C++ 代码:
#include <bits/stdc++.h>
using namespace std;
char a[2][2] = {{'A', 'B'}, {'D', 'C'}};
string op, s, ans;
int main()
{
// ios::sync_with_stdio(false);
// cin.tie(0);
cin >> op >> s;
for (int i = 0; i < op.size(); i ++ )
{
if (op[i] == 'L')
{
// 逆时针
int temp = a[0][0];
a[0][0] = a[0][1];
a[0][1] = a[1][1];
a[1][1] = a[1][0];
a[1][0] = temp;
}
else if (op[i] == 'R')
{
// 顺时针
int temp = a[0][0];
a[0][0] = a[1][0];
a[1][0] = a[1][1];
a[1][1] = a[0][1];
a[0][1] = temp;
}
if (s[i] == 'o') ans += a[0][0];
}
cout << ans << endl;
return 0;
}