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

1. 画正方形
题目大意
输入 ,输出一个 的大写字母正方形。第 行第 列从 开始,每往右一个位置字母后移一位;下一行开头也比上一行开头后移一位; 后面回到 。
解题思路
第 行第 列的字母偏移量是:
所以字符为:
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. 勾股数
题目大意
给定 ,统计有多少组三元组 满足:
并且:
这样的三元组叫做勾股数。
解题思路
枚举 和 ,计算:
如果 是完全平方数,并且 ,则找到一组答案。
注意要求 ,所以枚举时令 从 开始。
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. 百鸡问题
题目大意
每只公鸡 元,每只母鸡 元,每 只小鸡 元。现在有 元,要买 只鸡,问共有多少种购买方案。
解题思路
设公鸡数量为 ,母鸡数量为 ,小鸡数量为 。
需要满足:
并且:
由于每 只小鸡 元,所以 必须是 的倍数。
直接枚举公鸡和母鸡数量,小鸡数量由 得出。
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. 画三角形
题目大意
输入 ,输出一个由大写字母组成的三角形。第 行 个字母,第 行 个字母,依此类推。字母从 到 循环使用。
解题思路
用一个变量记录当前应该输出的字母编号。
每输出一个字符,编号加 。
编号对 取模即可实现 到 的循环。
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. 找素数
题目大意
给定两个正整数 ,统计区间 内有多少个素数。
解题思路
判断一个数 是否为素数,只需要检查 到 之间有没有数能整除 。
如果没有,则 是素数。
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. 自幂数判断
题目大意
自幂数指一个 位数,它每一位数字的 次方之和等于它本身。输入多个正整数,判断每个数是否是自幂数。
解题思路
对于一个数 :
- 先求它有多少位,记为 ;
- 拆出每一位数字 ;
- 累加 ;
- 判断累加结果是否等于原数。
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 字矩阵
题目大意
输入奇数 ,输出一个 的 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;
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. 数字黑洞
题目大意
给定一个三位数,每次把它的三个数字重新排列成最大数和最小数,然后用最大数减最小数,重复这个过程,最终会得到 。输出需要变换多少次。
解题思路
每次操作:
- 拆出百位、十位、个位;
- 排序;
- 组成最大数和最小数;
- 用最大数减最小数;
- 计数加 。
直到结果变成 。
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. 小杨做题
题目大意
小杨第 天做 道题,第 天做 道题。从第 天开始,每天做题数等于前两天做题数之和。如果某一天做题数大于等于 ,之后就不再做题。求到第 天为止总共做了多少题。
解题思路
这是一个类似斐波那契数列的模拟题。
依次计算每天做题数量:
每天把 加入答案。
如果某天 ,这一天仍然计入答案,但之后停止。
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 字矩阵
题目大意
输入奇数 ,输出一个 的 H 字矩阵。最左列和最右列是 ,中间一行的中间部分是 ,其余位置是 。
解题思路
设中间行为:
对于位置 :
- 如果 或 ,输出 ;
- 否则如果 ,输出 ;
- 否则输出 。
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. 乘法问题
题目大意
输入 个正整数,要求计算它们的乘积。如果乘积超过 ,输出 ,否则输出乘积。
解题思路
用变量 维护乘积。
每乘入一个数后,如果 ,就可以标记超过限制。
为了防止数值继续变大,可以把 固定成 。
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. 小杨的日字矩阵
题目大意
输入奇数 ,输出一个 的日字矩阵。最左列和最右列是 ,第一行、最后一行、中间一行的中间部分是 ,其余位置是 。
解题思路
设中间行为:
对于位置 :
- 如果 或 ,输出 ;
- 否则如果 、 或 ,输出 ;
- 否则输出 。
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. 平方之和
题目大意
输入 个正整数 ,判断每个 是否可以表示为两个正整数的平方和:
其中 都是正整数。
解题思路
由于 ,所以 最大不会超过 。
对每个 ,枚举 和 ,判断是否有:
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. 计数
题目大意
给定 和 ,统计从 到 的所有正整数中,数字 一共出现了多少次。
解题思路
枚举 到 的每个数。
对于每个数,逐位拆数字。
如果某一位等于 ,答案加 。
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. 数位之和
题目大意
输入 个正整数,如果一个数的数位和是 的倍数,则它是美丽数字。判断每个数是否是美丽数字。
解题思路
对每个数求数位和。
如果:
输出 ,否则输出 。
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 字矩阵
题目大意
输入奇数 ,输出一个 的 N 字矩阵。第一列、最后一列、主对角线位置输出 ,其余位置输出 。
解题思路
对于位置 :
- 如果 ,在第一列;
- 如果 ,在最后一列;
- 如果 ,在主对角线。
满足任意一个条件输出 。
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. 寻找数字
题目大意
给定正整数 ,判断是否存在正整数 满足:
如果存在,输出 ;否则输出 。有多组测试数据。
解题思路
因为:
而:
所以只需要枚举 从 到 。
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. 数位和
题目大意
输入 个正整数,求这些正整数的数位和中的最大值。
解题思路
依次读入每个数,计算它的数位和。
用变量 维护目前出现过的最大数位和。
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. 等差矩阵
题目大意
输入 ,输出一个 行 列的矩阵,其中第 行第 列的值为:
这个矩阵每一行、每一列都是等差数列。
解题思路
按照题意直接输出即可。
双重循环枚举行和列,输出 。
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. 时间跨越
题目大意
给定当前时间 年 月 日 时,以及 小时后,求新的年月日时。
解题思路
因为 ,可以直接逐小时模拟,或者先加到小时上,再处理进位。
这里采用小时进位:
- ;
- 如果 ,日期加 ,小时减 ;
- 如果日期超过当月天数,月份加 ;
- 如果月份超过 ,年份加 。
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. 数三角形
题目大意
直角三角形两条直角边为 ,面积为:
当 都是不超过 的正整数时,统计有多少个不同的直角三角形面积是整数。交换 视为同一个三角形。
解题思路
面积是整数,当且仅当:
是偶数。
因为交换 视为同一个三角形,所以只枚举:
如果 是偶数,答案加 。
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. 幂和数
题目大意
如果一个正整数 可以表示成两个 的非负整数次幂之和:
则称它为幂和数。给定区间 ,求其中有多少个幂和数。
解题思路
因为 ,可以枚举所有 的幂。
然后枚举两个幂的和,如果在 中,就标记为幂和数。
最后统计被标记的数字个数。
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. 优美的数字
题目大意
如果一个正整数的所有数位都相同,则称它是优美的。给定 ,求不超过 的正整数中有多少个优美数字。
解题思路
因为 ,直接枚举 到 。
把每个数转成字符串,判断所有字符是否都等于第一个字符。
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. 菱形
题目大意
输入奇数 ,输出一个 的菱形。菱形边界用 \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. 环保能量球
题目大意
小杨每行走 公里获得 点能量。每行走 公里,额外获得 点能量。给定行走距离 和奖励间隔 ,求总能量。
解题思路
基础能量是 。
额外奖励次数是:
所以总能量为:
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. 黄金格
题目大意
给定 ,矩形地图中格子坐标为 。如果满足:
则该格子是黄金格。求黄金格数量。
解题思路
直接枚举所有格子。
为了避免使用浮点数,可以把不等式两边平方。
但注意右边必须非负。
令:
如果 ,一定不满足。
否则判断:
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. 数数
题目大意
如果一个正整数的所有数位中恰好包含 个数字 ,则称它是美丽的。给定 ,统计区间 中有多少个美丽数。
解题思路
因为:
所以可以直接枚举 到 。
对每个数拆位,统计数字 出现次数。
如果刚好出现 次,答案加 。
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. 画画
题目大意
输入 ,绘制一个 的正方形。四个顶点用 ,上下边用 ,左右边用 ,内部用 。
解题思路
对于位置 :
- 四个角:输出 ;
- 第一行或最后一行:输出 ;
- 第一列或最后一列:输出 ;
- 其余位置:输出 。
判断顺序很重要,角要最先判断。
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;
}
京公网安备11010802045784号