- 西中经开竞赛期末测试
【题解】西中经开竞赛期末测试
- @ 2026-2-4 21:46:00
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;
}
T1 TooY0ung 的数字游戏
难度:没有难度,简单数学计算。
算法:数学,模拟。
子任务 ( 分):由于 ,题目中又保证了 ,所以 TooY0ung 的数字永远无法超过 TooSimple ,输出 即可。
子任务 ( 分):保证了 ,,所以直接计算 即可。
子任务 ( 分):满分做法除了无解情况,其实就是计算 ,需要注意如果可以整除,答案要 ,不能整除向上取整就好。
C++ 代码:
#include <bits/stdc++.h>
using namespace std;
int x, y, a, b;
int main()
{
cin >> x >> y >> a >> b;
if (a <= b) puts("-1");
else
{
if ((y - x) % (a - b) == 0) cout << (y - x) / (a - b) + 1 << endl;
else cout << (y - x + a - b - 1) / (a - 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;
}
T2 TooY0ung 的美食之旅
难度:循环,条件判断。
算法:数学,模拟。
子任务 ( 分):由于输入的全部都是 ,所以输出 就好了。
子任务 ( 分):没有 的话只需要关注数字发生了几次改变即可。
子任务 ( 分):其实只要在代码中统计有没有 出现,记录开心不开心即可,用一些变量存储以上各种情况,很容易实现代码。
C++ 代码:
#include <bits/stdc++.h>
using namespace std;
int n, x, no2, happy, unhappy, ans;
int main()
{
cin >> n;
for (int i = 1; i <= n; i ++ )
{
cin >> x;
if (x != 2 && no2 == 0)
{
no2 = 1;
if (x == 1) unhappy = 1;
else happy = 1;
}
if (no2 == 1 && x == 2) continue;
if (no2 == 1 && happy == 1 && x == 1 && unhappy == 0)
happy = 0, unhappy = 1, ans ++ ;
else if (no2 == 1 && unhappy == 1 && x == 3 && happy == 0)
unhappy = 0, happy = 1, ans ++ ;
}
cout << ans << 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;
}
T3 TooY0ung 的 WrongAnswer
难度:循环、字符串。
算法:字符串处理。
子任务 ( 分):只有小写字母只要查找是否有小写的 就行了,这里可以直接用 find 函数就行。
子任务 ( 分):只有大写字母就需要找一下 。
子任务 ( 分):满分做法其实就是把字母全变大写或者小写,找 “WRONGANSWER” 和 “wronganswer” 即可,在看同学们代码的时候,有一些不正确的写法被我的类似于 “WWRONGANSWER” 数据卡掉了,同学们可以课下再改一下。
C++ 代码:
#include <bits/stdc++.h>
using namespace std;
string s;
string wa = "wronganswer";
int main()
{
cin >> s;
int len = (int)s.size();
for (int i = 0; i < len; i ++ )
if (s[i] >= 'A' && s[i] <= 'Z') s[i] += 'a' - 'A';
if (s.find("wronganswer") != s.npos) puts("Yes");
else puts("No");
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;
}
T4 TooY0ung 的等差数列
难度:用学生的话说,可以叫智商测验题。
算法:。
只说正解吧:正解就是输出 就行,因为题目中写了数列长度大于等于 ,所以可以长度为 。
C++ 代码:
#include <bits/stdc++.h>
using namespace std;
int x;
int main()
{
cin >> x;
cout << 1 << endl;
cout << x << endl;
return 0;
}
1 comments
-
Myobot @ 2026-2-4 21:46:19
同学你好,感谢你分享的题解。看得出你对这些题目有深入的理解,并且整理得很详细。
不过,作为教练,我想提醒你和其他同学几点:
关于题解分享的注意事项
-
直接提供完整代码的风险:虽然你的题解很详细,但直接给出完整代码可能会让一些同学失去独立思考的机会。更好的方式是:
- 描述算法思路和关键步骤
- 指出易错点和边界情况
- 提供伪代码或核心逻辑片段
-
启发式学习的重要性:对于T2“每数一位”,你提到了“容易发现规律”,但为什么会出现1-9的循环?这个规律的本质是什么?
- 提示:考虑数字根(digital root)的性质
- 数字根的计算公式:
dr(n) = 1 + (n-1) % 9(当n≠0时) - 这能解释为什么会出现循环
对部分题目的深入思考
T3“数串质数”
你的两种解法都很好,但可以进一步优化:
- 质数判断只需要到
sqrt(n),你已经做到了 - 对于四位数的质数判断,可以预处理1000-9999的所有质数,用筛法会更高效
- 思考:为什么题目要求四位数不能以0开头?这在字符串处理中如何体现?
T4“四数转盘”
你的模拟解法是正确的,但可以引导同学思考更数学化的解法:
- 将A,B,C,D映射为0,1,2,3
- 左转相当于
(当前值+1)%4 - 右转相当于
(当前值+3)%4(即-1取模) - 这样可以直接计算而不需要实际旋转数组
给其他同学的建议
如果你在刷这些题目时遇到困难:
- 先独立思考:尝试自己写出解题思路,哪怕不完整
- 从小数据开始:先解决子任务1,理解题意
- 寻找规律:像T2那样,打印小数据观察模式
- 考虑优化:当暴力解法超时时,思考数学性质或数据结构优化
关于代码风格
你的代码风格清晰,但建议:
- 添加更多注释,特别是算法关键步骤
- 使用更有意义的变量名
- 考虑使用函数封装重复逻辑(如质数判断)
希望这些建议对你有帮助。继续加油,期待看到你更多的解题分享!
😄 1 -
- 1