推荐

GESP C++ 二级历年真题题解

_Separation 2026-5-17 20:27:16 16 浏览 0 点赞 0 收藏

GESP C++ 二级历年真题题解

1. 画正方形

题目大意

输入 nn,输出一个 n×nn \times n 的大写字母正方形。第 11 行第 11 列从 A\texttt{A} 开始,每往右一个位置字母后移一位;下一行开头也比上一行开头后移一位;Z\texttt{Z} 后面回到 A\texttt{A}

解题思路

ii 行第 jj 列的字母偏移量是:

i+j2i+j-2

所以字符为:

A+(i+j2)mod26\texttt{A} + (i+j-2) \bmod 26

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            char ch = 'A' + (i + j - 2) % 26;
            printf("%c", ch);
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

2. 勾股数

题目大意

给定 nn,统计有多少组三元组 (a,b,c)(a,b,c) 满足:

a2+b2=c2a^2+b^2=c^2

并且:

1abcn1 \le a \le b \le c \le n

这样的三元组叫做勾股数。

解题思路

枚举 aabb,计算:

c2=a2+b2c^2=a^2+b^2

如果 c2c^2 是完全平方数,并且 cnc \le n,则找到一组答案。

注意要求 aba \le b,所以枚举时令 bbaa 开始。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    int Ans = 0;
    for (int a = 1; a <= n; a++) {
        for (int b = a; b <= n; b++) {
            int c2 = a * a + b * b;
            int c = sqrt(c2);
            if (c * c == c2 && c <= n) Ans++;
        }
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

3. 百鸡问题

题目大意

每只公鸡 xx 元,每只母鸡 yy 元,每 zz 只小鸡 11 元。现在有 nn 元,要买 mm 只鸡,问共有多少种购买方案。

解题思路

设公鸡数量为 aa,母鸡数量为 bb,小鸡数量为 cc

需要满足:

a+b+c=ma+b+c=m

并且:

a×x+b×y+cz=na \times x + b \times y + \frac{c}{z}=n

由于每 zz 只小鸡 11 元,所以 cc 必须是 zz 的倍数。

直接枚举公鸡和母鸡数量,小鸡数量由 mabm-a-b 得出。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int x, y, z, n, m;
inline void solve() {
    cin >> x >> y >> z >> n >> m;
    int Ans = 0;
    for (int a = 0; a <= m; a++) {
        for (int b = 0; b <= m - a; b++) {
            int c = m - a - b;
            if (c % z == 0) {
                int cost = a * x + b * y + c / z;
                if (cost == n) Ans++;
            }
        }
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

4. 画三角形

题目大意

输入 nn,输出一个由大写字母组成的三角形。第 1111 个字母,第 2222 个字母,依此类推。字母从 A\texttt{A}Z\texttt{Z} 循环使用。

解题思路

用一个变量记录当前应该输出的字母编号。

每输出一个字符,编号加 11

编号对 2626 取模即可实现 A\texttt{A}Z\texttt{Z} 的循环。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    int Now = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
            printf("%c", ('A' + Now % 26));
            Now++;
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

5. 找素数

题目大意

给定两个正整数 A,BA,B,统计区间 [A,B][A,B] 内有多少个素数。

解题思路

判断一个数 xx 是否为素数,只需要检查 22x\sqrt{x} 之间有没有数能整除 xx

如果没有,则 xx 是素数。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int a, b;
bool isPrime(int x) {
    if (x < 2) return false;
    for (int i = 2; i * i <= x; i++) if (x % i == 0) return false;
    return true;
}
inline void solve() {
    cin >> a >> b;
    int Ans = 0;
    for (int i = a; i <= b; i++) {
        if (isPrime(i)) {
            Ans++;
        }
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

6. 自幂数判断

题目大意

自幂数指一个 NN 位数,它每一位数字的 NN 次方之和等于它本身。输入多个正整数,判断每个数是否是自幂数。

解题思路

对于一个数 xx

  1. 先求它有多少位,记为 lenlen
  2. 拆出每一位数字 dd
  3. 累加 dlend^{len}
  4. 判断累加结果是否等于原数。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
long long power(int a, int b) {
    long long Res = 1;
    for (int i = 1; i <= b; i++) Res *= a;
    return Res;
}
bool check(int x) {
    int t = x;
    int len = 0;
    while (t > 0) {
        len++;
        t /= 10;
    }
    t = x;
    long long Sum = 0;
    while (t > 0) {
        int d = t % 10;
        Sum += power(d, len);
        t /= 10;
    }
    return Sum == x;
}
inline void solve() {
    int x; cin >> x;
    if (check(x)) printf("T\n");
    else printf("F\n");
}
int main() {
    int _ = 1; cin >> _;
    while (_--) solve();
    return 0;
}

7. 小杨的 X 字矩阵

题目大意

输入奇数 NN,输出一个 N×NN \times N 的 X 字矩阵。两条对角线为 +\texttt{+},其余位置为 -\texttt{-}

解题思路

一个位置 (i,j)(i,j) 在两条对角线上,当且仅当:

i=ji=j

或者:

i+j=N+1i+j=N+1

满足条件输出 +\texttt{+},否则输出 -\texttt{-}

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (i == j || i + j == n + 1) {
                printf("+");
            } else {
                printf("-");
            }
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

8. 数字黑洞

题目大意

给定一个三位数,每次把它的三个数字重新排列成最大数和最小数,然后用最大数减最小数,重复这个过程,最终会得到 495495。输出需要变换多少次。

解题思路

每次操作:

  1. 拆出百位、十位、个位;
  2. 排序;
  3. 组成最大数和最小数;
  4. 用最大数减最小数;
  5. 计数加 11

直到结果变成 495495

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n, a[N];
int op(int x) {
    a[0] = x / 100;
    a[1] = x / 10 % 10;
    a[2] = x % 10;
    sort(a, a + 3);
    int mn = a[0] * 100 + a[1] * 10 + a[2];
    int mx = a[2] * 100 + a[1] * 10 + a[0];
    return mx - mn;
}
inline void solve() {
    cin >> n;
    int Ans = 0;
    while (n != 495) {
        n = op(n);
        Ans++;
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

9. 小杨做题

题目大意

小杨第 11 天做 aa 道题,第 22 天做 bb 道题。从第 33 天开始,每天做题数等于前两天做题数之和。如果某一天做题数大于等于 mm,之后就不再做题。求到第 NN 天为止总共做了多少题。

解题思路

这是一个类似斐波那契数列的模拟题。

依次计算每天做题数量:

fi=fi1+fi2f_i=f_{i-1}+f_{i-2}

每天把 fif_i 加入答案。

如果某天 fimf_i \ge m,这一天仍然计入答案,但之后停止。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
long long a, b, m, n;
inline void solve() {
    cin >> a >> b >> m >> n;
    long long Ans = 0;
    if (n >= 1) {
        Ans += a;
        if (a >= m) {
            printf("%lld\n", Ans);
            return;
        }
    }
    if (n >= 2) {
        Ans += b;
        if (b >= m) {
            printf("%lld\n", Ans);
            return;
        }
    }
    long long x = a;
    long long y = b;
    for (int day = 3; day <= n; day++) {
        long long z = x + y;
        Ans += z;
        if (z >= m) break;
        x = y;
        y = z;
    }
    printf("%lld\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

10. 小杨的 H 字矩阵

题目大意

输入奇数 NN,输出一个 N×NN \times N 的 H 字矩阵。最左列和最右列是 |\texttt{|},中间一行的中间部分是 -\texttt{-},其余位置是 a\texttt{a}

解题思路

设中间行为:

mid=N+12mid=\frac{N+1}{2}

对于位置 (i,j)(i,j)

  • 如果 j=1j=1j=Nj=N,输出 |\texttt{|}
  • 否则如果 i=midi=mid,输出 -\texttt{-}
  • 否则输出 a\texttt{a}

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    int mid = (n + 1) / 2;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (j == 1 || j == n) {
                printf("|");
            } else if (i == mid) {
                printf("-");
            } else {
                printf("a");
            }
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

11. 乘法问题

题目大意

输入 nn 个正整数,要求计算它们的乘积。如果乘积超过 10610^6,输出 >1000000\texttt{>1000000},否则输出乘积。

解题思路

用变量 ansans 维护乘积。

每乘入一个数后,如果 ans>1000000ans>1000000,就可以标记超过限制。

为了防止数值继续变大,可以把 ansans 固定成 10000011000001

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    long long Ans = 1;
    for (int i = 1, x; i <= n; i++) {
        cin >> x;
        Ans *= x;
        if (Ans > 1000000) {
            Ans = 1000001;
        }
    }
    if (Ans > 1000000) printf(">1000000\n");
    else printf("%lld\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

12. 小杨的日字矩阵

题目大意

输入奇数 NN,输出一个 N×NN \times N 的日字矩阵。最左列和最右列是 |\texttt{|},第一行、最后一行、中间一行的中间部分是 -\texttt{-},其余位置是 x\texttt{x}

解题思路

设中间行为:

mid=N+12mid=\frac{N+1}{2}

对于位置 (i,j)(i,j)

  • 如果 j=1j=1j=Nj=N,输出 |\texttt{|}
  • 否则如果 i=1i=1i=Ni=Ni=midi=mid,输出 -\texttt{-}
  • 否则输出 x\texttt{x}

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    int mid = (n + 1) / 2;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (j == 1 || j == n) {
                printf("|");
            } else if (i == 1 || i == n || i == mid) {
                printf("-");
            } else {
                printf("x");
            }
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

13. 平方之和

题目大意

输入 nn 个正整数 aia_i,判断每个 aia_i 是否可以表示为两个正整数的平方和:

x2+y2=aix^2+y^2=a_i

其中 x,yx,y 都是正整数。

解题思路

由于 ai106a_i \le 10^6,所以 x,yx,y 最大不会超过 10001000

对每个 aia_i,枚举 xxyy,判断是否有:

x2+y2=aix^2+y^2=a_i

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
bool check(int a) {
    for (int x = 1; x * x <= a; x++) {
        for (int y = 1; y * y <= a; y++) {
            if (x * x + y * y == a) {
                return true;
            }
        }
    }
    return false;
}
int a;
inline void solve() {
    cin >> a;
    if (check(a)) printf("Yes\n");
    else printf("No\n");
}
int main() {
    int _ = 1; cin >> _;
    while (_--) solve();
    return 0;
}

14. 计数

题目大意

给定 nnkk,统计从 11nn 的所有正整数中,数字 kk 一共出现了多少次。

解题思路

枚举 11nn 的每个数。

对于每个数,逐位拆数字。

如果某一位等于 kk,答案加 11

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int ct(int x, int k) {
    int Cnt = 0;
    while (x > 0) {
        if (x % 10 == k) {
            Cnt++;
        }
        x /= 10;
    }
    return Cnt;
}
int n, k;
inline void solve() {
    cin >> n >> k;
    int Ans = 0;
    for (int i = 1; i <= n; i++) Ans += ct(i, k);
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

15. 数位之和

题目大意

输入 nn 个正整数,如果一个数的数位和是 77 的倍数,则它是美丽数字。判断每个数是否是美丽数字。

解题思路

对每个数求数位和。

如果:

Summod7=0Sum \bmod 7=0

输出 Yes\texttt{Yes},否则输出 No\texttt{No}

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int ok(int x) {
    int Sum = 0;
    while (x > 0) {
        Sum += x % 10;
        x /= 10;
    }
    return Sum;
}
int x;
inline void solve() {
    cin >> x;
    if (ok(x) % 7 == 0) printf("Yes\n");
    else printf("No\n");
}
int main() {
    int _ = 1; cin >> _;
    while (_--) solve();
    return 0;
}

16. 小杨的 N 字矩阵

题目大意

输入奇数 mm,输出一个 m×mm \times m 的 N 字矩阵。第一列、最后一列、主对角线位置输出 +\texttt{+},其余位置输出 -\texttt{-}

解题思路

对于位置 (i,j)(i,j)

  • 如果 j=1j=1,在第一列;
  • 如果 j=mj=m,在最后一列;
  • 如果 i=ji=j,在主对角线。

满足任意一个条件输出 +\texttt{+}

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int m;
inline void solve() {
    cin >> m;
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) {
            if (j == 1 || j == m || i == j) {
                printf("+");
            } else {
                printf("-");
            }
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

17. 寻找数字

题目大意

给定正整数 aa,判断是否存在正整数 bb 满足:

a=b4a=b^4

如果存在,输出 bb;否则输出 1-1。有多组测试数据。

解题思路

因为:

a108a \le 10^8

而:

1004=108100^4=10^8

所以只需要枚举 bb11100100

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int ok(int a) {
    for (int b = 1; b <= 100; b++) {
        if (b * b * b * b == a) {
            return b;
        }
    }
    return -1;
}
int a;
inline void solve() {
    cin >> a;
    printf("%d\n", ok(a));
}
int main() {
    int _ = 1; cin >> _;
    while (_--) solve();
    return 0;
}

18. 数位和

题目大意

输入 nn 个正整数,求这些正整数的数位和中的最大值。

解题思路

依次读入每个数,计算它的数位和。

用变量 AnsAns 维护目前出现过的最大数位和。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
long long S(long long x) {
    long long Sum = 0;
    while (x > 0) {
        Sum += x % 10;
        x /= 10;
    }
    return Sum;
}
int n;
inline void solve() {
    cin >> n;
    long long Ans = 0;
    while (n--) {
        long long x; cin >> x;
        Ans = max(Ans, S(x));
    }
    printf("%lld\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

19. 等差矩阵

题目大意

输入 n,mn,m,输出一个 nnmm 列的矩阵,其中第 ii 行第 jj 列的值为:

i×ji \times j

这个矩阵每一行、每一列都是等差数列。

解题思路

按照题意直接输出即可。

双重循环枚举行和列,输出 i×ji \times j

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n, m;
inline void solve() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            printf("%d", i * j);
            if (j < m) printf(" ");
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

20. 时间跨越

题目大意

给定当前时间 yymmddhh 时,以及 kk 小时后,求新的年月日时。

解题思路

因为 k24k \le 24,可以直接逐小时模拟,或者先加到小时上,再处理进位。

这里采用小时进位:

  1. h=h+kh=h+k
  2. 如果 h24h \ge 24,日期加 11,小时减 2424
  3. 如果日期超过当月天数,月份加 11
  4. 如果月份超过 1212,年份加 11

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
bool isLeap(int y) {
    return y % 400 == 0 || (y % 4 == 0 && y % 100 != 0);
}
int days(int y, int m) {
    if (m == 2) {
        if (isLeap(y)) return 29;
        return 28;
    }
    if (m == 1 || m == 3 || m == 5 || m == 7 ||
        m == 8 || m == 10 || m == 12) {
        return 31;
    }
    return 30;
}
int y, m, d, h, k;
inline void solve() {
    cin >> y >> m >> d >> h >> k;
    h += k;
    while (h >= 24) {
        h -= 24;
        d++;
        if (d > days(y, m)) {
            d = 1;
            m++;
            if (m > 12) {
                m = 1;
                y++;
            }
        }
    }
    printf("%d %d %d %d\n", y, m, d, h);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

21. 数三角形

题目大意

直角三角形两条直角边为 a,ba,b,面积为:

ab2\frac{ab}{2}

a,ba,b 都是不超过 nn 的正整数时,统计有多少个不同的直角三角形面积是整数。交换 a,ba,b 视为同一个三角形。

解题思路

面积是整数,当且仅当:

abab

是偶数。

因为交换 a,ba,b 视为同一个三角形,所以只枚举:

1abn1 \le a \le b \le n

如果 a×ba \times b 是偶数,答案加 11

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    long long Ans = 0;
    for (int a = 1; a <= n; a++) {
        for (int b = a; b <= n; b++) {
            if ((a * b) % 2 == 0) {
                Ans++;
            }
        }
    }
    printf("%lld\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

22. 幂和数

题目大意

如果一个正整数 nn 可以表示成两个 22 的非负整数次幂之和:

n=2x+2yn=2^x+2^y

则称它为幂和数。给定区间 [l,r][l,r],求其中有多少个幂和数。

解题思路

因为 r104r \le 10^4,可以枚举所有 22 的幂。

然后枚举两个幂的和,如果在 [l,r][l,r] 中,就标记为幂和数。

最后统计被标记的数字个数。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int l, r;
inline void solve() {
    cin >> l >> r;
    vector<int> p;
    for (int x = 1; x <= r; x *= 2) {
        p.push_back(x);
    }
    vector<int> ok(r + 1, 0);
    for (int i = 0; i < (int)p.size(); i++) {
        for (int j = 0; j < (int)p.size(); j++) {
            int s = p[i] + p[j];
            if (l <= s && s <= r) {
                ok[s] = 1;
            }
        }
    }
    int Ans = 0;
    for (int i = l; i <= r; i++) if (ok[i]) Ans++;
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

23. 优美的数字

题目大意

如果一个正整数的所有数位都相同,则称它是优美的。给定 nn,求不超过 nn 的正整数中有多少个优美数字。

解题思路

因为 n2025n \le 2025,直接枚举 11nn

把每个数转成字符串,判断所有字符是否都等于第一个字符。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
bool good(int x) {
    string s = to_string(x);
    for (int i = 1; i < (int)s.size(); i++) if (s[i] != s[0]) return false;
    return true;
}
int n;
inline void solve() {
    cin >> n;
    int Ans = 0;
    for (int i = 1; i <= n; i++) {
        if (good(i)) {
            Ans++;
        }
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

24. 菱形

题目大意

输入奇数 nn,输出一个 n×nn \times n 的菱形。菱形边界用 \texttt{#},其余位置用 .\texttt{.}

解题思路

设中心位置为:

c=n+12c=\frac{n+1}{2}

菱形边界满足曼哈顿距离:

ic+jc=c1|i-c|+|j-c|=c-1

满足条件输出 \texttt{#},否则输出 .\texttt{.}

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    int c = (n + 1) / 2;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if (abs(i - c) + abs(j - c) == c - 1) {
                printf("#");
            } else {
                printf(".");
            }
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

25. 环保能量球

题目大意

小杨每行走 11 公里获得 11 点能量。每行走 xx 公里,额外获得 11 点能量。给定行走距离 nn 和奖励间隔 xx,求总能量。

解题思路

基础能量是 nn

额外奖励次数是:

nx\left\lfloor \frac{n}{x} \right\rfloor

所以总能量为:

n+nxn+\left\lfloor \frac{n}{x} \right\rfloor

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n, x;
inline void solve() {
    cin >> n >> x;
    printf("%d\n", (n + n / x));
}
int main() {
    int _ = 1; cin >> _;
    while (_--) solve();
    return 0;
}

26. 黄金格

题目大意

给定 H,W,xH,W,x,矩形地图中格子坐标为 (r,c)(r,c)。如果满足:

r2+c2x+rc\sqrt{r^2+c^2} \le x+r-c

则该格子是黄金格。求黄金格数量。

解题思路

直接枚举所有格子。

为了避免使用浮点数,可以把不等式两边平方。

但注意右边必须非负。

令:

v=x+rcv=x+r-c

如果 v<0v < 0,一定不满足。

否则判断:

r2+c2v2r^2+c^2 \le v^2

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int h, w, x;
inline void solve() {
    cin >> h >> w >> x;
    int Ans = 0;
    for (int r = 1; r <= h; r++) {
        for (int c = 1; c <= w; c++) {
            long long v = x + r - c;
            if (v >= 0) {
                long long left = 1LL * r * r + 1LL * c * c;
                long long right = v * v;
                if (left <= right) Ans++;
            }
        }
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

27. 数数

题目大意

如果一个正整数的所有数位中恰好包含 33 个数字 2\texttt{2},则称它是美丽的。给定 L,RL,R,统计区间 [L,R][L,R] 中有多少个美丽数。

解题思路

因为:

R106R \le 10^6

所以可以直接枚举 LLRR

对每个数拆位,统计数字 2\texttt{2} 出现次数。

如果刚好出现 33 次,答案加 11

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int ct(int x) {
    int Cnt = 0;
    while (x > 0) {
        if (x % 10 == 2) {
            Cnt++;
        }
        x /= 10;
    }
    return Cnt;
}
int l, r;
inline void solve() {
    cin >> l >> r;
    int Ans = 0;
    for (int i = l; i <= r; i++) {
        if (ct(i) == 3) {
            Ans++;
        }
    }
    printf("%d\n", Ans);
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

28. 画画

题目大意

输入 nn,绘制一个 n×nn \times n 的正方形。四个顶点用 +\texttt{+},上下边用 -\texttt{-},左右边用 |\texttt{|},内部用 *\texttt{*}

解题思路

对于位置 (i,j)(i,j)

  • 四个角:输出 +\texttt{+}
  • 第一行或最后一行:输出 -\texttt{-}
  • 第一列或最后一列:输出 |\texttt{|}
  • 其余位置:输出 *\texttt{*}

判断顺序很重要,角要最先判断。

C++ 代码

#include <bits/stdc++.h>
#define LOG(FMT...) fprintf(stderr, FMT)
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int read(){
    int x = 0,f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
    while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
int n;
inline void solve() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            if ((i == 1 || i == n) && (j == 1 || j == n)) {
                printf("+");
            } else if (i == 1 || i == n) {
                printf("-");
            } else if (j == 1 || j == n) {
                printf("|");
            } else {
                printf("*");
            }
        }
        printf("\n");
    }
}
int main() {
    int _ = 1;
    while (_--) solve();
    return 0;
}

评论

0 条
还没有评论。