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;
}