# 官方题解 | 欢乐赛#69题解
2026-03-18 10:52:31
发布于:浙江
官方题解 | 欢乐赛#69题解
赛纲介绍
本次题目的总体题目难度如下,各位选手可以借此评估一下自身的技术水平
| 题目编号 | 题目名称 | 题目难度 |
|---|---|---|
| T1 | 皓仔的颜文字 | 入门 |
| T2 | 皓仔的地理课 | 入门 |
| T3 | 皓仔的字符变换 | 入门 |
| T4 | 皓仔的螺旋遍历 | 入门 |
| T5 | 皓仔的单调质数求和 | 普及- |
| T6 | 皓仔的最优抉择 | 普及- |
T1 皓仔的颜文字
题目大意
按照输出样例, 输出 行颜文字。
题解思路
输出三行颜文字,使用 endl 进行换行即可。
参考代码
#include<bits/stdc++.h>
using namespace std;
int main(){
cout << ">w<" << endl;
cout << "XD" << endl;
cout << "(^_^)" << endl;
}
T2 皓仔的地理课
题目大意
皓仔正在学习地理知识,今天的内容是根据降水量进行地理区域的划分:
一个地区根据一年的总降水量(单位:毫米)可以划分成湿润区,半湿润区,半干旱区以及干旱区。
给出某地区全年的总降水量(单位:毫米),要求他根据降水情况判断该地区属于哪一种地理类型。
题解思路
多分支结构练习题,使用连续的 if-else-if 进行多分支判定:
当全年总降水量 时, 判定为湿润区,
否则当 全年总降水量时,判定为半湿润区,
否则当 全年总降水量时,判定为半干旱区,
否则该地区为干旱区。
参考代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
cin>>n;
if(n>=800)
cout<<"湿润区";
else if(n>=400)
cout<<"半湿润区";
else if(n>=200)
cout<<"半干旱区";
else
cout<<"干旱区";
return 0;
}
T3 皓仔的字符变换
题目大意
给定一个字符串 ,以及一个整数 。
对于字符串的每个字符 ,进行如下操作:
-
将字符 的编码值加上 ,得到一个新字符;
-
如果这个新字符属于以下三类之一:
- 数字字符
0到9 - 大写字母
A到Z - 小写字母
a到z
那么输出该新字符;
- 数字字符
-
否则输出
-1。
题解思路
本题在输入字符串 之后,直接遍历其中的每一个字符 . 对于变化之后的结果 , 判定是否属于字母或者数字,只要属于其中之一,那么输出对应的字符 char(c + x), 记得写类型转换以字符的形式输出。而如果不属于其中之一,则直接输出 -1 即可。
参考代码
#include <bits/stdc++.h>
using namespace std;
string s;
int x;
int main(){
cin >> s >> x;
for(int i = 0; i < s.size(); i++) {
int num = s[i] + x;
if(num >= 'A' && num <= 'Z' || num >= 'a' && num <= 'z' || num >= '0' && num <= '9')
cout << char(num) << ' ';
else cout << -1 << ' ';
}
return 0;
}
T4 皓仔的螺旋遍历
题目大意
对于一个 的二维数组 ,按照从外圈到内圈,一圈一圈访问,输出路径上所有的点。
具体来说,先输出最外层一圈:从左上角开始,先向右走,再向下走,再向左走,最后向上走。
输出完最外层后,再继续输出下一层,直到所有元素都被输出恰好一次。
题解思路
本题最直接的思路就是可以对于每一圈单独用四个循环来进行输出,分别输出这一圈的上边,右边,下边以及左边。
但是此类题目有更为方便的解决方法,也就是模拟螺旋遍历的路径。注意到遍历的方向是向右,向下,向左,向上,四个方向不断循环。
因此可以建立方向数组存储四个方向,按照当前方向不断前进,当前方已经超出了地图外,或者是已经经过的点,则改变到下一个方向继续前进,一直到完整地经过了 个点。
参考代码
#include <bits/stdc++.h>
using namespace std;
const int N=1005;
int n,x=1,y=1,cnt=1;
int a[N][N];
bool vis[N][N];
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
int main(){
cin>>n;
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
cin>>a[i][j];
}
}
cout<<a[1][1];
vis[1][1]=1;
while (cnt<n*n){
for (int i=0;i<4;i++){
while (1){
int nx=x+dx[i],ny=y+dy[i];
if (nx<1||nx>n||ny<1||ny>n||vis[nx][ny]){
break;
}
x=nx,y=ny;
cout<<' '<<a[x][y];
vis[x][y]=1;
cnt++;
}
}
}
return 0;
}
T5 皓仔的单调质数求和
题目大意
一个正整数被称为“单调质数”,当且仅当它同时满足以下两个条件:
- 它是一个质数;
- 它的十进制表示中,从左到右每一位数字单调不减。
请你计算从 到 之间所有“单调质数”的总和。
题解思路
本题的数据范围不大,因此可以直接遍历 到 ,判定该数字是否是单调质数,累加进答案中。
判定质数的方法可以直接使用试除法,复杂度 ,
判定是否是单调数字,则可以进行数位分解判定,从低位到高位数位分解的过程中,观察是否每次分解出来的数字都大于等于前一位,复杂度 。
参考代码
#include <bits/stdc++.h>
using namespace std;
int n,ans;
bool f(int x){
if(x <= 1) return false;
for(int i = 2; i * i <= x; i++){
if(x % i == 0) return false; //试除判质数
}
int pre = 10;
while(x) {
if(x % 10 > pre) return false;
pre = x % 10;
x /= 10;
}
return true;
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++) {
if(f(i)) ans += i;
}
cout << ans << endl;
}
T6 皓仔的最优抉择
题目大意
给定一个第 轮操作都会给出两个整数 和 ,每次必须从下面两种方式中选择一种执行:
- 将当前数字变为
- 将当前数字变为
每一轮进行二选一使得最终手中的数字尽可能大。
由于最终结果可能非常大,你只需要输出最大结果对 取模后的值。
题解思路
本题的一个容易踩坑的点是,不应该使用取模之后的数字直接用来进行加法和乘法的计算,可能会做出错误的选择。
我们可以使用一个变量 来保存到目前为止的最大值, 虽然最大值会远远超出 int 的范围,但是由于数据范围不超过 , 因此可以将 的上限设定为 , 不会影响我们的正确抉择:
对于乘法来说: 乘以 或者乘以 都是没有意义的,而乘以 意味着翻倍。 当 的值大于 时,就可以保证乘法的收益大于等于加法。
因此我们只需要每次比较 和 哪一个更大,即可得到合理的答案,记得每一次运算都要取模。
参考代码
#include <bits/stdc++.h>
using namespace std;
int M = 1e9 + 7;
int main(){
long long n, x;
cin >> n >> x;
long long s = x;
for(int i = 1; i <= n; i++) {
int y, z;
cin >> y >> z;
if(s + y > s * z) {
x = x + y;
}
else x = x * z;
s = max(s, x);
s = min(s, 1000000LL);
x %= M;
}
cout << x << endl;
}
全部评论 2
T6 策略分析参考代码
#include <bits/stdc++.h> using namespace std; int main(){ long long n,x; cin>>n>>x; if(n<0||n>1000000||x<0||x>1000000){ cout<<"errornx"<<endl; } int flag=0; if(x>=1000000){ flag=1; } for(int i=1;i<=n;i++){ long long y,z; cin>>y>>z; if(y<0||y>1000000||z<0||z>1000000){ cout<<"erroryz"<<endl; } if(z<=1){ x=(x+y); if(x>=1000000){ flag=1; } x=x%1000000007; } else if(flag==1){ x=x*z%1000000007; } else{ if(x+y>x*z){ x=x+y; } else{ x=x*z; } if(x>=1000000){ flag=1; } x=x%1000000007; } } cout<<x<<endl; return 0; }昨天 来自 浙江
0T4 矩阵螺旋访问参考代码
#include <bits/stdc++.h> using namespace std; int a[1010][1010]; int main(){ int n; cin>>n; if(n<0||n>1000){ cout<<"errorn"<<endl; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; if(a[i][j]<0||a[i][j]>1000000000){ cout<<"erroraij"<<endl; } } } int u=1; int d=n; int l=1; int r=n; int num=0; while(num<n*n){ for(int j=l;j<=r;j++){ cout<<a[u][j]<<" "; num++; } u++; for(int i=u;i<=d;i++){ cout<<a[i][r]<<" "; num++; } r--; for(int j=r;j>=l;j--){ cout<<a[d][j]<<" "; num++; } d--; for(int i=d;i>=u;i--){ cout<<a[i][l]<<" "; num++; } l++; } return 0; }分别表示还需要输出的上下左右的边界范围。
昨天 来自 浙江
0



















有帮助,赞一个