C语言之打印图形专题

前言

最近练习了一些关于图形打印的问题,发现考察的实际上是对嵌套循环语句的理解,以及对变量之间关系的把握。可以帮助我们加深对循环、条件判断、控制流等基本编程概念的理解,同时培养逻辑思维能力。

好了,废话不多说,下面是我对常见图形打印题目的分析与代码实现。

(文章末尾有彩蛋哦~)

一、打印线段图案

题目描述
多实例测试,输入一个整数n,(1<=n<=50),输出由“*”组成的线段,输出占一行。

样例输入
4
17

样例输出

在这里插入图片描述

  • 题意分析
    通过循环打印n次*来实现这个功能。

  • 代码实现

#include<stdio.h>
int 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

样例输出

在这里插入图片描述

  • 题意分析
    使用嵌套循环打印,外层循环控制行数,内层循环控制每行输出的*个数,并在每个*后加上一个空格。
  • 代码实现
#include<stdio.h>
int 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 <stdio.h>

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 <stdio.h>

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)//第一行和第一列都输出1
				coef = 1;
			else
				coef = 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个*

    注意:每个星号后面都有一个空格。

  • 代码实现

#include<stdio.h>
int 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 <stdio.h>

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

样例输出

在这里插入图片描述

  • 题意分析
  • 代码实现
#include<stdio.h>
int main()
{
    int n, i, j;
    
    // 循环读取输入的整数,直到遇到文件结束符(EOF)
    while(scanf("%d", &n) != EOF)
    {
        // 打印上半部分
        for(i = 0; i < n; i++)
        {
            // 打印星号,每行开始的星号个数为 n-i
            for(j = 0; j < n - i; j++)
            {
                printf("* ");
            }
            printf("\n");
        }
        
        // 打印下半部分
        for(i = 2; i < n + 1; i++)
        {
            // 打印星号,每行的星号个数为 i
            for(j = 0; j < i; j++)
            {
                printf("* ");
            }
            printf("\n");
        }
    }
    
    return 0;
}

五、打印菱形

1.打印实心菱形

题目描述
输入一个整数n(2<=n<=50),表示菱形边的长度,即字符“*”的个数。输出一个规格为n*n的菱形

样例输入
3
5

样例输出

在这里插入图片描述

  • 题意分析
    使用两层嵌套的循环来打印菱形,上半部分和下半部分分开处理。

    对于上半部分,外层循环控制行数,内层循环先打印一定数量的空格,然后再打印一定数量的星号,以形成菱形的每一行。
    对于下半部分,同样使用两层循环来打印,但是这次是逆序打印空格和星号,以形成菱形的下半部分。

  • 代码实现

#include <stdio.h>
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 <stdio.h>
#include <stdlib.h>

int main()
{
	int i, j, n;

	scanf("%d", &n);

	// 打印上半部分
	for (i = 1; i <= n; i++)
	{
		// 打印空格,每行开始的空格数为 n-i
		for (j = 1; j <= n - i; j++)
			printf(" ");
		// 打印数字1到i
		for (j = 1; j <= i; j++)
			printf("%d", j);
		// 打印数字i-1到1
		for (j = i - 1; j >= 1; j--)
			printf("%d", j);
		// 换行
		printf("\n");
	}

	// 打印下半部分
	for (i = n - 1; i >= 1; i--)
	{
		// 打印空格,每行开始的空格数为 n-i
		for (j = 1; j <= n - i; j++)
			printf(" ");
		// 打印数字1到i
		for (j = 1; j <= i; j++)
			printf("%d", j);
		// 打印数字i-1到1
		for (j = i - 1; j >= 1; j--)
			printf("%d", j);
		// 换行
		printf("\n");
	}

	return 0;
}

3.打印空心菱形

题目描述
输入一个整数n,(2<=n<=20),输出一个空心菱形,其中每个边由n个*组成。

样例输入
5

样例输出

在这里插入图片描述

  • 题意分析
    使用一个外层循环来控制菱形的行数,分别处理菱形的上半部分和下半部分。

    对于菱形的每一行,内层循环根据当前行数来控制输出空格和星号,从而实现空心菱形的效果。

  • 代码实现

#include<stdio.h>
//关键是找到循环打印次数与行数的关系 
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 控制了下半部分的输出条件。根据这两个条件,程序在合适的位置输出星号或空格,从而打印出漏斗形状。
  • 代码实现
#include<stdio.h>

int 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 ( a 1 + a n ) 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 漏 斗 < = n u m , ( 4 ) S_{n漏斗} <= num, (4) Sn<=num4联立上式,并带入a1= 1,d = 2
    可以解出 n < = n u m + 1 2 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<stdio.h>
#include<math.h>

int main()
{
 int num, n, i , j;
 char x;
 scanf("%d %c", &num, &x); // 输入一个正整数num和一个字符x

	n = sqrt((num + 1) / 2); // 计算边长n

	for(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 <stdio.h>

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 <stdio.h>
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<stdio.h>
#include<windows.h>

int 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;
}
  • 样例
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白吉馍也好吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值