202409-1 数位之和
题目描述
小杨有 n 个正整数,他认为一个正整数是美丽数字当且仅当该正整数每一位数字的总和是 7 的倍数。
小杨想请你编写一个程序判断 n 个正整数哪些是美丽数字。
输入格式
第一行包含一个正整数 n,表示正整数个数。
之后 n 行,每行一个包含一个正整数 a_i。
输出格式
对于每个正整数输出一行一个字符串,如果是美丽数字则输出 Yes
,否则输出 No
。
样例输入 1
3
7
52
103
样例输出 1
Yes
Yes
No
提示
对全部的测试数据,保证 1 \leq n \leq 10^5,1 \leq a_i \leq 10^5。
代码解析
对每组数字进行数位剥离求和,再去判断数位和是否为 7 的倍数即可
#include<bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
while(n--) {
int a, sum = 0;
cin >> a;
while(a) {
sum += a % 10;
a /= 10;
}
if (sum % 7 == 0) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
202409-2 小杨的 N 字矩阵
题目描述
小杨想要构造一个 m \times m 的 N 字矩阵(m 为奇数),这个矩阵的从左上角到右下角的对角线、第 1 列和第 m 列都是半角加号 +
,其余都是半角减号 -
。例如,一个 5 \times 5 的 N 字矩阵如下:
+---+
++--+
+-+-+
+--++
+---+
请你帮小杨根据给定的 m 打印出对应的 N 字矩阵。
输入格式
输入只有一行包含一个正整数 m。
输出格式
输出对应的 N 字矩阵。
样例输入 1
5
样例输出 1
+---+
++--+
+-+-+
+--++
+---+
提示
【数据规模与约定】
对全部的测试数据,保证 3 \leq m \leq 49 且 m 是奇数。
代码解析
找规律,每一行的第一列与最后一列是
+
,主对角线(i == j
)是+
,其余都是-
#include<bits/stdc++.h>
using namespace std;
int main() {
int m;
cin >> m;
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++)
if (i == j || j == 0 || j == m-1)
cout << '+';
else
cout << "-";
cout << endl;
}
return 0;
}
202406-1 平方之和
题目描述
小杨有 n 个正整数 a_1,a_2,\dots,a_n,他想知道对于所有的 i (1\le i\le n),是否存在两个正整数 x 和 y 满足 x\times x+y \times y=a_i。
输入格式
第一行包含一个正整数 n,代表正整数数量。
之后 n 行,每行包含一个正整数,代表 a_i。
输出格式
对于每个正整数 a_i,如果存在两个正整数 x 和 y 满足 x\times x+y \times y=a_i,输出 Yes
,否则输出 No
。
样例输入 1
2
5
4
样例输出 1
Yes
No
提示
对于第一个正整数,存在 1\times 1+2 \times 2=5,因此答案为 Yes
。
对于全部数据,保证有 1 \le n \le 10,1 \le a_i \le 10^6。
代码解析
每个数字 a,我们需要找到一个 x 和一个 y,满足
x*x + y*y == a
,我们在这里使用枚举法,通过 for 循环枚举x
的值,然后通过a - x*x
得到b
,如果b
的算数平方根是整数的话,这个整数就是符合条件的 y,如果b
的算数平方根不是整数,说明当前 x 的取值没有符合题意的整数 y,如果 x 枚举结束之后依然没有找到符合条件的y
,输出 No。
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, a;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a;
bool flag = false;
for (int x = 1; x*x < a; x++) {
int b = a - x*x;
// 判断 b 的算数平方根是不是整数
int y = sqrt(b);
if (y * y == b) {
flag = true;
break;
}
}
if (flag) cout << "Yes" << endl;
else cout << "No" << endl;
}
return 0;
}
202406-2 计数
题目描述
小杨认为自己的幸运数是正整数 k(注:保证 1 \le k\le 9)。小杨想知道,对于从 1 到 n 的所有正整数中, k 出现了多少次。
输入格式
第一行包含一个正整数 n。
第二行包含一个正整数 k。
输出格式
输出从 1 到 n 的所有正整数中, k 出现的次数。
样例输入 1
25
2
样例输出 1
9
提示
从 1 到 25 中,2 出现的正整数有 2,12,20,21,22,23,24,25 ,一共出现了 9 次。
对于全部数据,保证有 1 \le n\le 1000,1 \le k\le 9。
代码解析
对 1~n 之间的每一个数字进行十进制数位剥离,统计
k
出现了多少次即可,注意不要对循环变量i
直接进行数位剥离,会导致死循环
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, k, cnt = 0;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
int t = i;
while (t) {
if (t % 10 == k) cnt++;
t /= 10;
}
}
cout << cnt;
return 0;
}
202403-1 乘法问题
题目描述
小 A 最初刚刚学习了乘法,为了帮助他练习,我们给他若干个正整数,并要求他将这些数乘起来。
对于大部分题目,小 A 可以精确地算出答案,不过,若这些数的乘积超过 10^6,小 A 就不会做了。
请你写一个程序,告诉我们小 A 会如何作答。
输入格式
第一行一个整数 n,表示正整数的个数。
接下来 n,每行一个整数 a。小 A 需要将所有的 a 乘起来。
输出格式
输出一行,如果乘积超过 10^6,则输出 >1000000
;否则输出所有数的乘积。
样例输入 1
2
3
5
样例输出 1
15
样例输入 2
3
100
100
100
样例输出 2
1000000
样例输入 3
4
100
100
100
2
样例输出 3
>1000000
提示
对全部的测试数据,保证 1 \leq n \leq 50,1 \leq a \leq 100。
代码解析
这里使用一个小技巧,主函数中遇到
return 0;
程序就会直接结束,所以当乘积 > 1000000,就直接输出内容,终止程序
注意
ans
是累计相乘的变量,所以初始值是 1
#include<iostream>
using namespace std;
int main() {
int n, x, ans = 1;
cin >> n;
while (n--) {
cin >> x;
ans *= x;
if (ans > 1000000) {
cout << ">1000000";
return 0;
}
}
cout << ans;
return 0;
}
202403-2 小杨的日字矩阵
题目描述
小杨想要构造一个 N\times N 的日字矩阵(N 为奇数),具体来说,这个矩阵共有 N 行,每行 N 个字符,其中最左列、最右列都是 |
,而第一行、最后一行、以及中间一行(即第 \frac{N+1}{2} 行)的第 2\sim N-1 个字符都是 -
,其余所有字符都是半角小写字母 x
。例如,一个 N = 5 日字矩阵如下:
|---|
|xxx|
|---|
|xxx|
|---|
请你帮小杨根据给定的 N 打印出对应的“日字矩阵”。
输入格式
一行一个整数 N(5\leq N \leq 49,保证 N 为奇数)。
输出格式
输出对应的“日字矩阵”。
请严格按格式要求输出,不要擅自添加任何空格、标点、空格等任何符号。你一个恰好输出 N 行,每行除了换行符外恰好包含 N 个字符,这些字符要么是 -
,要么是 |
,要么是 x
。你的输出必须和标准答案完全一致才能得分,请在提交前仔细检查。
样例输入 1
5
样例输出 1
|---|
|xxx|
|---|
|xxx|
|---|
样例输入 2
7
样例输出 2
|-----|
|xxxxx|
|xxxxx|
|-----|
|xxxxx|
|xxxxx|
|-----|
代码解析
观察输出
'-', 'x', '|'
的坐标规律即可
第一行
i == 1
,最后一行i == N
,中间行i == (N+1)/2
#include<iostream>
using namespace std;
int main() {
int N;
cin >> N;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (j == 1 || j == N)
cout << '|';
else if (i == 1 || i == (N+1)/2 || i == N)
cout << '-';
else
cout << 'x';
}
cout << endl;
}
return 0;
}
202312-1 小杨做题
题目描述
为了准备考试,小杨每天都要做题。第 1 天,小杨做了 a 道题;第 2 天,小杨做了 b 道题;从第 3 天起,小杨每天做的题目数量是前两天的总和。
此外,小杨还规定,当自己某一天做了大于或等于 m 题时,接下来的所有日子里,他就再也不做题了。
请问,到了第 N 天,小杨总共做了多少题呢?
输入格式
总共 4 行。第一行一个整数 a,第二行一个整数 b,第三行一个整数 m,第四行一个整数 N。
保证 0 \le a,b \le 10;a,b<M<1,000,000;3 \le N \le 364。
输出格式
一行一个整数,表示小杨 N 天里总共做了多少题目。
样例输入 1
1
2
10
5
样例输出 1
19
样例输入 2
1
1
5
8
样例输出 2
12
提示
【样例解释 1】
小杨第一天做 1 题,第二天做 2 题,第三天做 1+2=3 题,第四天做 2+3=5 题,第五天做 3+5=8 题。因此他总共做了 1+2+3+5+8=19 题。
【样例解释 2】
小杨前 5 天分别做了 1,1,2,3,5 题,由于第 5 天小杨做了 5 题,而 m=5,于是小杨从此以后不再做题。因此小杨总共做了 1+1+2+3+5=12 题。
代码解析
注:已经学过数组或函数的同学可以使用数组递推或者递归函数
使用逐个递推的思想,每天的答题数量等于前两天之和,那么我们需要一个变量 n 来保存这一天答题的数量,然后将 b 赋值给 a, 将 n 赋值给 b,这样的话我们下一天就可以继续使用
a + b
来算出当天答题的数量
#include<iostream>
using namespace std;
int main() {
int a, b, m, N, n, sum;
cin >> a >> b >> m >> N;
// 记得加上第一天第二天的答题数量
sum = a + b;
// 一共 N 天,第1,2天的已经加了,从3开始
for (int i = 3; i <= N; i++) {
n = a + b;
a = b;
b = n;
sum += n;
if (n >= m)
break;
}
cout << sum;
return 0;
}
202312-2 小杨的H字矩阵
题目描述
小杨想要构造一个 N \times N 的 H 字矩阵(N 为奇数),具体来说,这个矩阵共有 N 行,每行 N 个字符,其中最左列、最右列都是 |
,而中间一行(即第\frac{N+1}{2}行)的第 2 \sim N-1 个字符都是 -
,其余所有字符都是半角小写字母 a
。例如,一个 N=5 的 H 字矩阵如下:
|aaa|
|aaa|
|---|
|aaa|
|aaa|
请你帮小杨根据给定的 N 打印出对应的“H 字矩阵”。
输入格式
一行一个整数 N(5\le N \le 49 ,保证 N 为奇数)。
输出格式
输出对应的“H 字矩阵”。
请严格按格式要求输出,不要擅自添加任何空格、标点、空行等任何符号。你应该恰好输出 N 行,每行除了换行符外恰好包含 N 个字符,这些字符要么是 - ,要么是 | ,要么是 a 。你的输出必须和标准答案完全一致才能得分,请在提交前仔细检查。
样例输入 1
5
样例输出 1
|aaa|
|aaa|
|---|
|aaa|
|aaa|
样例输入 2
7
样例输出 2
|aaaaa|
|aaaaa|
|aaaaa|
|-----|
|aaaaa|
|aaaaa|
|aaaaa|
代码解析
观察输出
'-', 'a', '|'
的坐标规律即可,题目中有给出中间一行的坐标计算方式 (第\frac{N+1}{2}行)
#include<iostream>
using namespace std;
int main() {
int N;
cin >> N;
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++) {
if (j == 1 || j == N)
cout << '|';
else if (i == (N+1)/2)
cout << '-';
else
cout << 'a';
}
cout << endl;
}
return 0;
}
202309-1 小杨的 X 字矩阵
题目描述
小杨想要构造一个 的 X 字矩阵( 为奇数),这个矩阵的两条对角线都是半角加号 +
,其余都是半角减号 -
。例如,一个 5 \times 5 的 X 字矩阵如下:
+---+
-+-+-
--+--
-+-+-
+---+
请你帮小杨根据给定的 打印出对应的“X 字矩阵”。
输入格式
一行一个整数 ( 5 \le N \le 49,保证为奇数)。
输出格式
输出对应的“X 字矩阵”。
请严格按格式要求输出,不要擅自添加任何空格、标点、空行等任何符号。你应该恰好输出 N 行,每行除了换行符外恰好包含 N 个字符,这些字符要么是 +
,要么是 -
。
样例输入 1
5
样例输出 1
+---+
-+-+-
--+--
-+-+-
+---+
样例输入 2
7
样例输出 2
+-----+
-+---+-
--+-+--
---+---
--+-+--
-+---+-
+-----+
代码解析
主对角线和副对角线需要输出
'+'
,其余为'-'
主对角线:
i == j
,副对角线i+j == n-1
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j || i + j == n-1)
cout << '+';
else
cout << '-';
}
cout << endl;
}
return 0;
}
202309-2 数字黑洞
题目描述
给定一个三位数,要求各位不能相同。例如,352 是符合要求的,112 是不符合要求的。将这个三位数的三个数字重新排列,得到的最大的数,减去得到的最小的数,形成一个新的三位数。对这个新的三位数可以重复上述过程。神奇的是,最终一定会得到 495!
试试看,重新排列 352,得到的最大数为 532,最小数为 235,它们的差是 297;变换 297,得到 972-279=693;变换 693,963-369=594;变换 594,954-459=495。因此,经过 4 次变换得到了 495。
现在,输入的三位数,你能通过编程得出,这个三位数经过多少次变换能够得到 495 吗?
输入格式
输入一行,包含一个符合要求的三位数 N。
输出格式
输出一行,包含一个整数 C,表示经过 C 次变换得到 495。
样例输入 1
352
样例输出 1
4
代码解析
- 使用三位数的数位剥离方法得到
a, b, c
,将a, b, c
从小到大排序- 用
a, b, c
组合的大数减去组合的小数
N
不等于 495 的时候重复执行以上 1 2 过程,过程中使用cnt
计数
#include<iostream>
using namespace std;
int main() {
int N, a, b, c, cnt = 0, sum = 0;
cin >> N;
while(N != 495) {
a = N % 10;
b = N / 10 % 10;
c = N / 100;
if (a > b) swap(a, b);
if (a > c) swap(a, c);
if (b > c) swap(b, c);
N = (c*100 + b*10 + a) - (a*100 + b*10 + c);
cnt++;
}
cout << cnt;
return 0;
}
202306-1 找素数
题目描述
小明刚刚学习了素数的概念:如果一个大于 1 的正整数,除了 1 和它自身外,不能被其他正整数整除,则这个正整数是素数。现在,小明想找到两个正整数 A 和 B 之间(包括 A 和 B)有多少个素数。
输入格式
输入只有一行两个正整数 A, B。约定 2 \le A \le B \le 1000。
输出格式
输出一行,包含一个整数 C,表示找到 C 个素数。
样例输入 1
2
10
样例输出 1
4
提示
在 2 和 10 之间有 4 个素数,分别为:2、3、5、7。
代码解析
使用 for 循环从 a 开始到 b 结束枚举,挨个判断并计数
#include<iostream>
#include<cmath>
using namespace std;
int main() {
int a, b, cnt = 0;
cin >> a >> b;
for (int i = a; i <= b; i++) {
bool flag = true;
for (int j = 2; j*j <= i; j++)
if (i % j == 0)
flag = false;
if (flag)
cnt++;
}
cout << cnt;
return 0;
}
202306-2 自幂数判断
题目描述
自幂数是指,一个 N 位数,满足各位数字 N 次方之和是本身。例如,153 是 3 位数,其每位数的 3 次方之和,1^3+5^3+3^3=153,因此 153 是自幂数;1634 是 4 位数,其每位数的 4 次方之和,1^4+6^4+3^4+4^4=1634,因此 1634 是自幂数。
现在,输入若干个正整数,请判断它们是否是自幂数。
输入格式
输入第一行是一个正整数 M,表示有 M 个待判断的正整数。约定 1 \le M \le 100。
从第 2 行开始的 M 行,每行一个待判断的正整数。约定这些正整数均小于 10^8。
输出格式
输出 M 行,如果对应的待判断正整数为自幂数,则输出英文大写字母 \texttt T,否则输出英文大写字母 \texttt F。
提示:不需要等到所有输入结束在依次输出,可以输入一个数就判断一个数并输出,再输入下一个数。
样例输入 1
3
152
111
153
样例输出 1
F
F
T
样例输入 2
5
8208
548834
88593477
12345
5432
样例输出 2
T
T
T
F
F
代码解析
每输入一个数,需要做以下几件事:
- 判断这个数是几位数(n 位)
- 循环 n 次,不断求每一位的 n 次方
#include<iostream>
using namespace std;
int main() {
// N 为题目中的 N 个数
// x 是每一个需要判断的数字
// n 代表 x 是个 n 位数
// sum_n 用来计算每个 x 每一位数的 n 次方
// sum 用来统计每个 x 每一位数的 n 次方之和
int N, x, n, xx, sum_n, sum;
cin >> N;
for (int i = 0; i < N; i++) {
cin >> x;
n = 0;
sum = 0;
// 将 x 的值保存到 xx 里面
// 使用 while 统计 x 的位数 n
xx = x;
while (xx != 0) {
n++;
xx /= 10;
}
xx = x;
// 循环 n 次,计算每一位数的 n 次方之和
for (int j = 0; j < n; j++) {
sum_n = 1;
// 循环 n 次,计算每一位数的 n 次方
for (int k = 0; k < n; k++)
sum_n *= xx % 10;
xx /= 10;
sum += sum_n;
}
if (sum == x)
cout << 'T' << endl;
else
cout << 'F' << endl;
}
return 0;
}
202303-1 画三角形
题目描述
输入一个正整数 n,请使用大写字母拼成一个这样的三角形图案(参考样例输入输出):三角形图案的第 1 行有 1 个字母,第 2 行有 2 个字母,以此类推;在三角形图案中,由上至下、由左至右依次由大写字母 \texttt{A}-\texttt{Z} 填充,每次使用大写字母 \texttt Z 填充后,将从头使用大写字母 \texttt A 填充。
输入格式
输入一行,包含一个正整数 n。约定 2 \le n \le 40。
输出格式
输出符合要求的三角形图案。注意每行三角形图案的右侧不要有多余的空格。
样例输入 1
3
样例输出 1
A
BC
DEF
样例输入 2
7
样例输出 2
A
BC
DEF
GHIJ
KLMNO
PQRSTU
VWXYZAB
代码解析
单独定义
char
变量,每次打印后加一,超出'Z'
重新变回'A'
。
#include<iostream>
using namespace std;
int main() {
char c = 'A';
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
cout << c++;
if (c > 'Z')
c = 'A';
}
cout << endl;
}
return 0;
}
202303-2 百鸡问题
题目描述
“百鸡问题”是出自我国古代《张丘建算经》的著名数学问题。大意为:
“每只公鸡 5 元,每只母鸡 3 元,每 3 只小鸡 1 元;现在有 100 元,买了 100 只鸡,共有多少种方案?”
小明很喜欢这个故事,他决定对这个问题进行扩展,并使用编程解决:如果每只公鸡 x 元,每只母鸡 y 元,每 z 只小鸡 1 元;现在有 n 元,买了 m 只鸡,共有多少种方案?
输入格式
输入一行,包含五个整数,分别为问题描述中的 x,y,z,n,m。约定 1 \le x,y,z \le 10,1 \le n,m \le 1000。
输出格式
输出一行,包含一个整数 C,表示有 C 种方案。
样例输入 1
5 3 3 100 100
样例输出 1
4
样例输入 2
1 1 1 100 100
样例输出 2
5151
提示
【样例 1 解释】
这就是问题描述中的“百鸡问题”。4 种方案分别为:
- 公鸡 0 只、母鸡 25 只、小鸡 75 只。
- 公鸡 4 只、母鸡 18 只、小鸡 78 只。
- 公鸡 8 只、母鸡 11 只、小鸡 81 只。
- 公鸡 12 只、母鸡 4 只、小鸡 84 只。
代码解析
枚举法,假设公鸡的数量为 i,母鸡的数量为 j 进行枚举,小鸡 k 的数量可以通过
m - i - j
得到,根据题意所花的钱是整数,所以 k 必须是 z 的倍数,验证三种鸡的价钱只和是否等于 n 即可。注意排除掉
k < 0
的情况。这道题也可以写三层嵌套,k 的取值从 z 开始,每次
k += z
#include<iostream>
using namespace std;
int main() {
int x, y, z, n, m, cnt = 0;
cin >> x >> y >> z >> n >> m;
for (int i = 0; i <= n/x; i++) {
for (int j = 0; j <= n/y; j++) {
int k = m - i - j;
if (k >= 0 && k % z == 0 && i*x + j*y + k/z == n)
cnt++;
}
}
cout << cnt;
return 0;
}