2028 字
10 分钟
GESP 2026年C++二级编程题解析
2026/03/14
2026/09/12

202603-1 数数#

题目描述

给定一个数,如果数中恰好存在3个2,则被称为美丽的数字。

现给定两个数 a,ba, b,其中 (a<ba < b),请输出它们之间(含端点)存在多少个美丽的数。

输入格式

输入一行两个整数 a,ba, b。

输出格式

输出一个整数,表示 aa 到 bb 之间美丽的数有多少个。

样例输入

2221 2223

样例输出

2

数据范围

0≤a,b≤1060 \le a, b \le 10^6

代码解析

这道题是一道典型的数位剥离问题,我们可以用一个循环去遍历 aa 到 bb 之间的所有数,对于每个数,我们用一个循环去遍历它的每一位,统计其中 2 的个数,若个数为 3 则答案加一,注意不要直接用 i 去剥离,循环结束后 i 变成 0,导致死循环。

#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b, ans = 0;
cin >> a >> b;
for (int i = a; i <= b; i++) {
int cnt = 0;
int j = i;
while (j != 0) {
if (j % 10 == 2) cnt++;
j /= 10;
}
if (cnt == 3) ans++;
}
cout << ans;
return 0;
}

202603-2 画画#

题目描述

给你一个单整数 nn,请输出一个 nn 行 nn 列的方阵。方阵的四个顶点是 +,第一行和第 nn 行的非顶点位置是 -,第 1 列和第 nn 列非顶点位置是 |,中间位置是 *。

输入格式

输入一个单整数 nn。

输出格式

nn 行 nn 列的方阵。

样例输入

5

样例输出

+---+
|***|
|***|
|***|
+---+

数据范围

n≤108n \le 10^8

代码解析

一道二级常考的画图问题,注意观察矩形中各种符号的规律即可,第一行和最后一行是 + 和 -,其他行是 | 和 *,分开处理即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
if (i == 1 || i == n) {
if (j == 1 || j == n) cout << '+';
else cout << '-';
} else {
if (j == 1 || j == n) cout << '|';
else cout << '*';
}
cout << endl;
}
return 0;
}

202606-1 完全平方数计数#

题目描述

小杨同学正在研究完全平方数。

平方: 一个数的平方等于这个数乘以这个数本身。

完全平方数: 指可以恰好表示为某个正整数的平方的数。

例如,99 是完全平方数,因为 9=32=3×39 = 3^2 = 3 \times 3;但 2727 不是,因为 2727 不能表示为任何正整数的平方。

给定两个正整数 ll 和 rr(保证 l≤rl \le r),小杨同学想知道 ll 到 rr 之间的所有正整数中(包含 ll 和 rr),有多少个数是完全平方数。

输入格式

输入两行,第一行为一个正整数 ll,第二行为一个正整数 rr。

输出格式

输出一个非负整数,表示 ll 到 rr 中,有多少个正整数是完全平方数。如果 ll 到 rr 中没有完全平方数,则输出 00。

样例输入 1

1
21

样例输出 1

4

提示

【样例解释 1】

在 11 到 2121 中,有以下 44 个整数是完全平方数: 1,4,9,161, 4, 9, 16。

【数据范围】

1≤l≤r≤20001 \le l \le r \le 2000。

代码解析

这道题和之前考过的题目类似,只需要利用 C++ 整数的特性,先求出 i 的平方根,保存到整数变量,再去求平方看是否等于 i 即可。

#include <bits/stdc++.h>
using namespace std;
int main() {
int l, r, cnt = 0;
cin >> l >> r;
for (int i = l; i <= r; i++) {
int a = sqrt(i);
if (a * a == i)
cnt++;
}
cout << cnt;
return 0;
}

202606-2 菱形#

题目描述

给定正整数 nn,在 (2n−1)×(2n−1)(2n - 1) \times (2n - 1) 个网格的画布中,使用字符画一个边长为 nn 个网格的菱形。其中,空白网格使用 ⋅\cdot 表示,菱形边所在的网格用 ++ 表示。

例如当 n=3n = 3 时,图形如下:

..+..
.+.+.
+...+
.+.+.
..+..

输入格式

输入一个正整数 nn;

输出格式

输出 2n−12n - 1 行,表示按要求画的菱形。

样例输入 1

4

样例输出 1

...+...
..+.+..
.+...+.
+.....+
.+...+.
..+.+..
...+...

提示

【数据范围】

3≤n≤153 \le n \le 15。

代码解析

这道题和 2025 年 9 月菱形唯一不同的点,就是输入的 n 代表的含义不同,只需要注意这一点就可以,方法有很多种,这里给出一种上下两部分分开输出的方法。

#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int m = 2*n-1;
// 先画上半部分
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
if (j == n + (i-1) || j == n - (i-1))
cout << '+';
else
cout << '.';
cout << endl;
}
// 下半部分 i 逆序即可,内层不变
for (int i = n-1; i >=1; i--) {
for (int j = 1; j <= m; j++)
if (j == n + (i-1) || j == n - (i-1))
cout << '+';
else
cout << '.';
cout << endl;
}
return 0;
}

202609-1 直角三角形#

题目描述

小双刚学会勾股定理,得知直角三角形的斜边的平方等于两直角边的平方和。

小双创造了直角三角形数列:数列前两项由小双指定,从第三项开始,数列中的每个数字的平方等于前两项的平方和。

例如,第一项是 3.0,第二项是 4.0,则第三项是 3.02+4.02=5.0\sqrt{3.0^2+4.0^2}=5.0。其中 x\sqrt{x} 表示 xx 的算术平方根,可以使用 C/C++/Python 标准库中对应函数计算。

小双给定了数列的前两项,并给定一个数列上限,想让你算算数列的第几项会超过小双给定的数列上限?

输入格式

输入三行,第一行一个浮点数是数列第一项,第二行一个浮点数是数列第二项,第三行一个浮点数表示数列上限。

输出格式

输出一个正整数,表示第几项开始会超过小双给定的数列上限。

样例输入1

3.0
4.0
10.0

样例输出1

6

代码解析

这道题考察的是滚动递推的过程,需要使用三个变量 a, b, t 来滚动递推,先求出下一个值 t,再将 b 赋值给 a,将 t 赋值给 b,当 t > 上限 直接结束循环。

#include <bits/stdc++.h>
using namespace std;
int main() {
double a, b, c, t;
cin >> a >> b >> c;
for (int i = 3; ; i++) {
t = sqrt(a*a + b*b);
if (t > c) {
cout << i;
break;
}
a = b;
b = t;
}
return 0;
}

202609-2 字符变换#

题目描述

小明有一个 8×168 \times 16 的画布(8 行 16 列),画布中的格子从上到下从左到右编号,左上的编号为 1,第一排最后一个的编号为 16,最后一排第一个编号为 113,右下为 128。

初始画布中的每个格子都是 *,随后小明会给定三个正整数,小明会将对应编号的格子变为该正整数对应的 ASCII 编码字符。

最后请帮小明输出整个画布。

输入格式

输入包含三行,每行一个正整数,表示需要替换的画布格子编号。

输出格式

输出 8×168\times16 的画布。

样例输入1

48
65
97

样例输出1

****************
****************
***********0****
****************
A***************
****************
a***************
****************

代码解析

这道题本质上还是画图类题,考查对于循环嵌套规律的使用,这道题的难点是你需要知道每一个位置的编号是几,通过观察数学规律,我们需要让两层循环都从 1 开始,这样每个位置的编号是 (i-1)*16 + j,接下来我们只需要分别判断每个位置的编号是不是三个数字之一就可以,数字转对应的 ASCII 编码,可以用 char() 来强制转换。

#include <bits/stdc++.h>
using namespace std;
int main() {
int a, b, c;
cin >> a >> b >> c;
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <=16; j++) {
int cnt = j+(i-1)*16;
if (a == cnt || b == cnt || c == cnt)
cout << char(cnt);
else
cout << '*';
}
cout << endl;
}
return 0;
}
GESP 2026年C++二级编程题解析
https://yezi.press/posts/gesp/gesp-cpp2-2026/
作者
Yezi 叶子
发布于
2026/03/14
许可协议
CC BY-NC-SA 4.0