目录
- 前言
- 一、打印线段图案
- 二、打印X形图案
- 三、打印三角形
- 1.打印直角三角形(实心)
- 2.打印直角三角形(空心)
- 3.打印杨辉三角
- 4.打印等边三角形(实心)
- 5.打印等边三角形(空心)
- 四、打印K型图案
- 五、打印菱形
- 1.打印实心菱形
- 2.打印数字菱形
- 3.打印空心菱形
- 六、打印沙漏(类似菱形)
- 1.基础·打印沙漏
- 2.进阶·打印由给定符号组成的最大的沙漏
- 七、打印正方形
- 1.打印实心正方形
- 2.打印空心正方形
- 彩蛋
前言
最近练习了一些关于图形打印的问题,发现考察的实际上是对嵌套循环语句的理解,以及对变量之间关系的把握。可以帮助我们加深对循环、条件判断、控制流等基本编程概念的理解,同时培养逻辑思维能力。
好了,废话不多说,下面是我对常见图形打印题目的分析与代码实现。
(文章末尾有彩蛋哦~)
一、打印线段图案
题目描述
多实例测试,输入一个整数n,(1<=n<=50),输出由“*
”组成的线段,输出占一行。
样例输入
4
17
样例输出
题意分析
通过循环打印n次*
来实现这个功能。代码实现
#includeint main(){int n = 0;while(scanf("%d", &n) != EOF)//多组输入{ int i = 0;for(i = 0;i < n; i++)//循环n次{printf("*");}printf("\n");//换行}return 0;}
二、打印X形图案
题目描述
多实例测试,输入一个整数n(2<=n<=50),打印一个规格为n*n
的X形图案。
样例输入
5
20
样例输出
- 题意分析
通过观察可以发现,所要打印的字符“X”,都在规格为n*n的正方形的对角线上,并且两条对角线分别满足 i = j
和i + j = n- 1
(如下图所示),所以可以写一个循环嵌套,里面if判断,若在这两条线上,打印X,否则打印空格。
- 代码实现
- #include<stdio.h>int main(){int n = 0;while(scanf("%d", &n) != EOF){int i = 0;for(i = 0; i < n; i++){int j = 0;for(j = 0; j < n; j++){if(i==j||j==(n-1-i)){printf("X");}else{printf(" ");}}printf("\n");//打印完一行,换行}}return 0;}
三、打印三角形
1.打印直角三角形(实心)
题目描述
输入一个整数n(2<=n<=50),表示三角形直角边字符“*
”的个数。输出一个直角三角形,每个直角边由n个“*
”组成,每个“*
”后有一个空格
样例输入
3
5
样例输出
- 题意分析
使用嵌套循环打印,外层循环控制行数,内层循环控制每行输出的*
个数,并在每个*
后加上一个空格。 - 代码实现
#includeint main(){int n = 0;while (scanf("%d", &n) != EOF){int i, j;for (i = 0; i < n; i++){for (j = 0; j <= i; j++){printf("* ");}printf("\n");}}return 0;}
2.打印直角三角形(空心)
题目描述
输入一个整数n(2<=n<=50),表示三角形直角边字符“*
”的个数。输出一个空心直角三角形,每个直角边由n个“*
”组成,每个“*
”后有一个空格
样例输入
3
5
6
样例输出
- 题意分析
- 与打印实心相比,在内层循环中,我们应根据当前行数来判断是在打印最左边的一列、最右边的一列,还是中间的空心部分,并做出相应的打印。
- 代码实现
#include int main(){int n, i, j;while(scanf("%d", &n) != EOF){for (i = 1; i <= n; i++){for (j = 1; j <= i; j++){// 打印第一行、最后一行和每行的第一个以及最后一个位置if (i == 1 || i == n || j == 1 || j == i){printf("* ");}else{printf("");//注意这里是两个空格,以保证格式一致}}printf("\n");}}return 0;}
3.打印杨辉三角
题目描述
输入一个整数n(1<=n<=20),输出杨辉三角的前n行,每个元素占6列,右对齐
样例输入
6
样例输出
题意分析
在直角杨辉三角形中,每一行的数字可以根据上一行的数字通过组合公式来计算得到。具体地,第i行的第j个数字可以由上一行的第j个数字和第j-1个数字通过组合公式计算得到。因此,在代码中,我们使用
coef = coef * (i - j + 1) / j
来计算直角杨辉三角形中每个位置的值。其中coef
表示当前位置的值,(i - j + 1)
表示上一行的第j个数字,j表示上一行的第(j-1)个数字。代码实现
#include int main(){int n, coef = 1, i, j;scanf("%d", &n);for (i = 0; i < n; i++){for (j = 0; j <= i; j++){if (j == 0 || i == 0)//第一行和第一列都输出1coef = 1;elsecoef = coef * (i - j + 1) / j;printf("%6d", coef);}printf("\n");}return 0;}
4.打印等边三角形(实心)
题目描述
多组输入,输入一个整数n(2<=n<=50),表示等边三角形边的长度,即字符“*
”的个数。
输出一个等边三角形,每个“*
”后有一个空格
样例输入
3
4
样例输出
题意分析
在每一行中,首先输出一定数量的空格,数量为n-1-i,其中i为当前行数。然后输出i+1个*
注意:每个星号后面都有一个空格。
代码实现
#includeint main(){int n = 0;while(scanf("%d", &n) != EOF){int i = 0;int j = 0;for(i = 0; i < n; i++){for(j = 0; j < n-1-i; j++){printf(" ");//打印一个空格}for(j = 0; j <= i; j++){printf("* ");}printf("\n");}}return 0;}
5.打印等边三角形(空心)
题目描述
多组输入,输入一个整数n(2<=n<=50),表示等边三角形边的长度,即字符“*
”的个数。
输出一个空心等边三角形,每个“*
”后有一个空格
样例输入
3
5
样例输出
题意分析
循环进行处理。在循环中,首先打印出三角形的第一行,即n-1个空格加上一个星号,然后换行。接下来是打印中间行,通过嵌套的循环控制空格和星号的输出,确保每一行都符合空心等边三角形的要求,然后换行。
最后,根据条件判断是否需要打印最后一行,如果n大于1,则打印最后一行的星号和空格。
代码实现
#include int main(){int n, i, j;while(scanf("%d", &n) != EOF){// 打印第一行for (i = 1; i < n; i++){printf(" ");}printf("*\n");// 打印中间行for (i = 2; i < n; i++){for (j = 1; j <= n - i; j++){printf(" ");}printf("*");for (j = 1; j <= 2 * i - 3; j++){printf(" ");}printf("*\n");}// 打印最后一行if (n > 1){for (i = 1; i <= n; i++){printf("* ");}printf("\n");}}return 0;}
四、打印K型图案
题目描述
输入一个整数n(2<=n<=50),表示最长行的长度,即*
的个数,输出由*
形成的K字点阵。
样例输入
3
5
样例输出
- 题意分析
- 代码实现
#includeint main(){int n, i, j;// 循环读取输入的整数,直到遇到文件结束符(EOF)while(scanf("%d", &n) != EOF){// 打印上半部分for(i = 0; i < n; i++){// 打印星号,每行开始的星号个数为 n-ifor(j = 0; j < n - i; j++){printf("* ");}printf("\n");}// 打印下半部分for(i = 2; i < n + 1; i++){// 打印星号,每行的星号个数为 ifor(j = 0; j < i; j++){printf("* ");}printf("\n");}}return 0;}
五、打印菱形
1.打印实心菱形
题目描述
输入一个整数n(2<=n<=50),表示菱形边的长度,即字符“*
”的个数。输出一个规格为n*n
的菱形
样例输入
3
5
样例输出
题意分析
使用两层嵌套的循环来打印菱形,上半部分和下半部分分开处理。对于上半部分,外层循环控制行数,内层循环先打印一定数量的空格,然后再打印一定数量的星号,以形成菱形的每一行。
对于下半部分,同样使用两层循环来打印,但是这次是逆序打印空格和星号,以形成菱形的下半部分。代码实现
#include int main(){int n, i, j;while (scanf("%d", &n) != EOF) // 输入菱形的行数n{for (i = 0; i < n; i++) // 打印上半部分菱形,从第一行到第n行{for (j = 0; j < n - i - 1; j++) // 打印空格,随着行数增加,空格数量递减{printf(" ");}for (j = 0; j < 2 * i + 1; j++) // 打印星号,根据行数确定每行的星号数量{printf("*");}printf("\n"); // 打印完一行,换行}for (i = n - 2; i >= 0; i--) // 打印下半部分菱形{for (j = 0; j < n - i - 1; j++) // 打印空格,随着行数减少,空格数量递增{printf(" ");}for (j = 0; j < 2 * i + 1; j++) // 打印星号,根据行数确定每行的星号数量{printf("*");}printf("\n"); // 打印完一行,换行}}return 0;}}
2.打印数字菱形
题目描述
输入一个整数n,(1≤n≤9),输出一个数字菱形,菱形中心为输入的数字,如下图所示
样例输入
5
样例输出
题意分析
对于上半部分,我们使用两层嵌套循环来打印:
外层循环控制行数,从第一行到输入的整数n。内层循环分三部分:1.打印空格,个数为 n-i,确保数字菱形居中对齐。
2.打印递增数字,从1到i。
3.打印递减数字,从i-1到1。这样就完成了上半部分的数字菱形打印。对于下半部分,同样使用两层嵌套循环来打印:
外层循环控制行数,从n-1到1。
内层循环的结构和上半部分类似,同样分为打印空格、递增数字和递减数字。代码实现
#include #include int main(){int i, j, n;scanf("%d", &n);// 打印上半部分for (i = 1; i <= n; i++){// 打印空格,每行开始的空格数为 n-ifor (j = 1; j <= n - i; j++)printf(" ");// 打印数字1到ifor (j = 1; j <= i; j++)printf("%d", j);// 打印数字i-1到1for (j = i - 1; j >= 1; j--)printf("%d", j);// 换行printf("\n");}// 打印下半部分for (i = n - 1; i >= 1; i--){// 打印空格,每行开始的空格数为 n-ifor (j = 1; j <= n - i; j++)printf(" ");// 打印数字1到ifor (j = 1; j <= i; j++)printf("%d", j);// 打印数字i-1到1for (j = i - 1; j >= 1; j--)printf("%d", j);// 换行printf("\n");}return 0;}
3.打印空心菱形
题目描述
输入一个整数n,(2<=n<=20),输出一个空心菱形,其中每个边由n个*
组成。
样例输入
5
样例输出
题意分析
使用一个外层循环来控制菱形的行数,分别处理菱形的上半部分和下半部分。对于菱形的每一行,内层循环根据当前行数来控制输出空格和星号,从而实现空心菱形的效果。
代码实现
#include//关键是找到循环打印次数与行数的关系 int main(){int n, i, j, k;scanf("%d", &n);/*上半部分*/ for(i = 0; i < n; i++){for(k = 0; k < n - i - 1; k++)//打印左空格(n-i-1个){printf(" ");}printf("*");//打印左半边的星星(1个) if(i > 0)//打印中间空格:因为第一行无空格,故加个判断,从第二行开始打印 {for(k = 0; k < 2 * i - 1; k++)//观察发现:中间空格个数呈1,3,5{printf(" ");} printf("*");//打印右半边的星星}printf("\n");//打印完一行,换行 }/*下半部分*/ for(i = n - 1; i > 0; i--){for(k = 0; k <= n - i - 1; k++)//打印左空格(i+1个){printf(" ");}printf("*");//打印左半边的星星(1个) if(i > 1)//打印中间空格:因为最后一行无空格,故加个判断,到倒数第二行结束 {for(k = 0; k < 2 * i - 3; k++)//观察发现:中间空格个数呈递减数列 {printf(" ");} printf("*");//打印右半边的星星}printf("\n");//打印完一行,换行 }return 0;}
六、打印沙漏(类似菱形)
1.基础·打印沙漏
题目描述
输入一个整数n,(2<=n<=20),输出一个沙漏,其中沙漏两端由n个*
组成。
样例输入
3
5
样例输出
- 题意分析
具体来说,条件i+j >= n-1 && i >= j
控制了上半部分的输出条件,条件i+j <= n-1 && i <= j
控制了下半部分的输出条件。根据这两个条件,程序在合适的位置输出星号或空格,从而打印出漏斗形状。 - 代码实现
#includeint main(){int n, i , j;scanf("%d", &n);for(i = 0; i < n; i++){for(j = 0; j < n; j++){if(i+j >= n-1 && i >= j || i+j <= n-1 && i <= j){printf("*");}else{printf(" ");}}printf("\n");}return 0;}
2.进阶·打印由给定符号组成的最大的沙漏
题目描述
输入1个正整数N(<=1000)和一个符号,中间以空格分隔。
首先打印出由给定符号组成的最大的沙漏形状,空一行,然后输出剩下没用掉的符号数
样例输入
19 *
样例输出
题意分析
此题难点在于如何求出最大符号个数,而整个漏斗的字符个数,实际为组成这个漏斗的两个三角形的符号个数减1。而一个三角形符号的个数怎么求呢?我们已知它每一行分别为1,3,5…由此自然想到了等差数列。首先,我们都知道:
a n= a 1+ ( n − 1 )d ,(1)a_{n}=a_{1}+ \left( n-1 \left) d\right. \right. , (1) an=a1+(n−1)d,(1) S n= n ( a1+ an)2,(2)S_{n}=\frac{n \left( a_{1}+a_{n}\right)}{2},(2) Sn=2n(a1+an),(2)刚才说过 S n漏斗 =2 S n−1,(3)S_{n漏斗}=2S_n-1,(3) Sn漏斗=2Sn−1,(3)假设给定了num
个符号,只需要满足 S n漏斗 <=num,(4)S_{n漏斗} <= num, (4) Sn漏斗<=num,(4)联立上式,并带入a1= 1,d = 2
可以解出n<=n u m + 12 n<=\sqrt\frac{ {num+1} }{2} n<=2num+1n
即为三角形的行数,如果是小数,则向下取整(在c语言中,恰好可以利用int的特性进行截断取整)。有了n,带入到(2)(3)式, 可得出打印沙漏所需要的字符个数为
2*n*n-1
而在打印部分,笔者通过限制条件进行打印。(与前面的打印X图形原理一样)
首先,通过观察可以发现,所要打印的字符,都在规格为n*n的正方形的两条对角线的上半部分交集,和下半部分交集,并且两条对角线分别满足 i = j
和i + j = 2 * n
(如下图所示)。
所以可以写一个循环嵌套,里面if判断,若在这两条线上交集和下交集,打印星星,否则打印空格。
- 代码实现
#include#includeint main(){ int num, n, i , j; char x; scanf("%d %c", &num, &x); // 输入一个正整数num和一个字符xn = sqrt((num + 1) / 2); // 计算边长nfor(i = 1; i <= 2 * n - 1; i++) {for(j = 1; j <= 2 * n - 1; j++){//if(i+j >= 2 * n && i >= j || i+j <= 2 * n && i <= j) {printf("%c", x); }else{printf(" "); }}printf("\n"); }printf("\n%d", num - 2 * n * n + 1); // 计算剩余未使用的数字并输出return 0;}
七、打印正方形
1.打印实心正方形
题目描述
输入一个整数n(2<=n<=20),表示正方形边的长度,即字符“*
”的个数。输出一个规格为n*n
的实心正方形
样例输入
3
5
样例输出
- 题意分析
使用两层循环控制行和列,每行打印n个’*’字符,然后换行,共打印n行,形成一个实心正方形。 - 代码实现
#include int main(){int n, i, j;while (scanf("%d", &n) != EOF){for (i = 0; i < n; i++){for (j = 0; j < n; j++){printf("* ");}printf("\n");}}return 0;}
2.打印空心正方形
题目描述
输入一个整数n(2<=n<=20),表示正方形边的长度,即字符“*
”的个数。输出一个规格为n*n
的实心正方形
样例输入
3
5
样例输出
- 题意分析
在空心正方形的打印中,我们需要判断每行每列的位置,如果在边界上则打印’*’,否则打印空格,从而形成空心效果。 - 代码实现
#include int main(){int n, i, j;while (scanf("%d", &n) != EOF){for (i = 0; i < n; i++){for (j = 0; j < n; j++){if (i == 0 || i == n - 1 || j == 0 || j == n - 1){printf("* ");}else{printf("");}}printf("\n");}}return 0;}
好了,现在你已经学会打印各类图形了。尝试打印一个爱心给对象吧~
彩蛋
这里用到的数学公式是:
- 代码实现
#include#includeint main(){double x, y;system("color 0c");//颜色设置为红for(y = 1.5; y > -1.5; y -= 0.1){for(x = -1.5; x < 1.5; x += 0.05){double a = x*x+y*y-1.0;if(a*a*a <= x*x*y*y*y){printf("*");}else{printf(" ");Sleep(6);//停顿六毫秒}}printf("\n");}return 0;}
- 样例