目录

  • 前言
    • 一、打印线段图案
    • 二、打印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 = ji + 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+(n1)d1 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=2Sn13假设给定了num个符号,只需要满足 S n漏斗 <=num,(4)S_{n漏斗} <= num, (4) Sn<=num4联立上式,并带入a1= 1,d = 2
    可以解出n<=n u m + 12 n<=\sqrt\frac{ {num+1} }{2} n<=2num+1 n即为三角形的行数,如果是小数,则向下取整(在c语言中,恰好可以利用int的特性进行截断取整)。

    有了n,带入到(2)(3)式, 可得出打印沙漏所需要的字符个数为2*n*n-1

而在打印部分,笔者通过限制条件进行打印。(与前面的打印X图形原理一样)

首先,通过观察可以发现,所要打印的字符,都在规格为n*n的正方形的两条对角线的上半部分交集,和下半部分交集,并且两条对角线分别满足 i = ji + 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;}
  • 样例