一道C语言入门题 “输出字符沙漏” 的解题思路
题目
http://oj.haizeix.com/problem/141
1.题目描述
输入一个正整数 n,并输出一个沙漏形,这个沙漏形有 2n+1 行,第一行有 2n+1 个字母,其中前 n+1 个字符是从 A 开始依次递增的,而后 n 个字符是由第 n+1 个字符开始依次递减的。之后的 n 行每行会少头尾两个字母。再之后的 n 行则正好是前 n 行反过来输出的结果。注意末尾不要有多余的输出。
2.输入
输入一个正整数 n。(0<n<26)
3.输出
按照样例输出。
4.样例
// 输入
2
// 输出
ABCBA
BCB
C
BCB
ABCBA
// 输入
3
// 输出
ABCDCBA
BCDCB
CDC
D
CDC
BCDCB
ABCDCBA
解题思路
- 用两层循环, 外层控制输出行数, 内层输出行内字符.
- 行内字符使用两个循环输出, 一个输出空格, 一个输出字符
- 外层一共2n+1行, 所以外层变量从0~2n, 变量记为i
- 找规律发现, 内层每行输出空格的个数先递增后递减, 记空格数量为a
当n=3时:
i=0, a=0
i=1, a=1
i=2, a=2
i=3, a=3
i=4, a=2
i=5, a=1
可以画出函数图像:
函数f(i)为: -abs(i - n) + n - 每行字母个数可以 N * 2 - 1 (N是自然数) 表示. 此时用同样的方法, 找到函数关系, 每行输出字母个数的函数为:
((abs(i - n)) + 1) * 2 - 1, 变量记为j
- 字母可以表示为 f(i, j) % 26 + ‘A’ 的形式, %26是为了保证数值在字符区间内
- 找规律, 先找到第一行的函数 -abs(j - n) + n,
第二行之后的字母与与行变量有关, 所以最终函数为:
-abs(j - n - abs(i-n) + n) + n
代码
#include <stdio.h>
#define abs(x) ((x)>0?(x):-(x))
int main() {
int n;
scanf("%d", &n);
for (int i=0; i<2*n+1; i++) {
for (int j=0; j<(-abs(i-n))+n; j++) {
printf(" ");
}
for (int j=0; j<((abs(i-n))+1)*2-1; j++) {
printf("%c", (-abs(j-abs(i-n))+n) % 26 + 'A');
}
printf("\n");
}
return 0;
}
坐标系画图网站
https://www.desmos.com/calculator?lang=zh-CN