(题目来源于牛客网题库)链接:https://www.nowcoder.com/ta/beginner-programmers
例题
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的菱形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20)。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的菱形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制2
输出:
代码语言:javascript复制 *
* *
* * *
* *
*
输入:
代码语言:javascript复制3
输出:
代码语言:javascript复制 *
* *
* * *
* * * *
* * *
* *
*
分析
这类题的做法比较多,因为for循环的套娃特性,每个人有每个人的逻辑,对于循环语句的控制变化多样,所以很长时间我都是试探着做这类题,每次做都头疼。后来做多了,发现了一个规律。
模版
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < ? ? ; j )
{
printf("* ");
}
printf("n");
}
return 0;
}
模版的套用
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0; //变量n用来存放用户输入的数据
int i = 0, j = 0; //变量i控制行数,变量j控制列数
while (~scanf("%d", &n))//这里是多组输入的简单写法
{
for (i = 0; i < n; i ) //最外层for循环打印一个n控制输出的行数
{
for (j = 0; j < ? ? ; j ) //这里固定格式,??内容挖坑待补
{
printf(" ");//这里打印出题目要求的字符组成,这里是此题的组成1(也就是空格)
}
for (j = 0; j < ? ? ; j )//同上
{
printf("* ");//这里打印出题目要求的字符组成,这里是此题的组成2(也就是* )
}
printf("n");//最外层循环打印的换行符,控制输出行数
}
for (i = 0; i < (n 1); i )//这个是输出了三行,所以是n 1行,为了方便理解我把n 1用括号括起来(n 1)
{
for (j = 0; j < ? ? ; j )
{
printf(" ");
}
for (j = 0; j < ? ? ; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
//下面阐述循环控制也就是??部分的写法,以此题为例
/* 第一个??打印了2个空格,观察其变化是2、1,可知表达式中必定有-i,n-i=2,所以这里填n-i。
第二个??打印了1个* ,观察其变化是1、2,可知表达式中必定有 i,i 1=1,所以这里填i 1。(或者前面写成<=)
第三个??打印了0个空格,观察其变化是0、1、2,可知表达式中必定有 i,i=0;所以这里填i即可
第四个??打印了3个* ,观察其变化是3、2、1,可知表达式中必定有-i,(n 1)-i=3,所以这里填n 1-i (或者前面写成<=) */
//综上所述,可写出这道题的正确答案如下。其他题以此类推
本题参考答案
代码语言:javascript复制#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - i; j )
{
printf(" ");
}
for (j = 0; j < i 1; j )
{
printf("* ");
}
printf("n");
}
for (i = 0; i < n 1; i )
{
for (j = 0; j < i; j )
{
printf(" ");
}
for (j = 0; j < n - i 1; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
相似题目验证模版的普适性及对于模版套用的巩固
正方形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的正方形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(1~20),表示正方形的长度,也表示输出行数。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的对应边长的正方形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制* * * *
* * * *
* * * *
* * * *
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制* * * * *
* * * * *
* * * * *
* * * * *
* * * * *
参考答案:
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
直角三角形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的直角三角形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示直角三角形直角边的长度,即“*”的数量,也表示输出行数。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的对应长度的直角三角形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制*
* *
* * *
* * * *
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制*
* *
* * *
* * * *
* * * * *
参考答案:
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < i 1; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
翻转直角三角形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的翻转直角三角形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示翻转直角三角形直角边的长度,即“*”的数量,也表示输出行数。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的对应长度的翻转直角三角形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制* * * * *
* * * *
* * *
* *
*
输入:
代码语言:javascript复制6
输出:
代码语言:javascript复制* * * * * *
* * * * *
* * * *
* * *
* *
*
参考答案:
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - i; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
带空格直角三角形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的带空格直角三角形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示直角三角形直角边的长度,即“*”的数量,也表示输出行数。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的对应长度的直角三角形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制 *
* *
* * *
* * * *
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制 *
* *
* * *
* * * *
* * * * *
参考答案:
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n ; i )
{
for (j = 0; j < n - i - 1; j )
{
printf(" ");
}
for (j = 0; j < i 1; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
金字塔图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的金字塔图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示金字塔边的长度,即“*”的数量,,也表示输出行数。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的金字塔,每个“*”后面有一个空格。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制 *
* *
* * *
* * * *
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制 *
* *
* * *
* * * *
* * * * *
参考答案:
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - i - 1; j )
{
printf(" ");
}
for (j = 0; j < i 1; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
翻转金字塔图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的翻转金字塔图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示翻转金字塔边的长度,即“*”的数量,也表示输出行数。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的金字塔,每个“*”后面有一个空格。
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制* * * * *
* * * *
* * *
* *
*
输入:
代码语言:javascript复制6
输出:
代码语言:javascript复制* * * * * *
* * * * *
* * * *
* * *
* *
*
参考答案:
代码语言:javascript复制#include <stdio.h>
int main(void)
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < i; j )
{
printf(" ");
}
for (j = 0; j < n - i; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
菱形图案
这个就是例题,我做到这题时找到的规律
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的菱形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20)。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的菱形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制2
输出:
代码语言:javascript复制 *
* *
* * *
* *
*
输入:
代码语言:javascript复制3
输出:
代码语言:javascript复制 *
* *
* * *
* * * *
* * *
* *
*
参考答案:
代码语言:javascript复制#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - i; j )
{
printf(" ");
}
for (j = 0; j < i 1; j )
{
printf("* ");
}
printf("n");
}
for (i = 0; i < n 1; i )
{
for (j = 0; j < i; j )
{
printf(" ");
}
for (j = 0; j < n - i 1; j )
{
printf("* ");
}
printf("n");
}
}
return 0;
}
K形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的K形图案。
原题尾端便有看不到的空格占位符这个隐藏坑,此处空格用“.”表示,其他题亦然。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20)。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的K形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制2
输出:
代码语言:javascript复制*.*.*.
*.*..
*...
*.*..
*.*.*.
输入:
代码语言:javascript复制3
输出:
代码语言:javascript复制*.*.*.*.
*.*.*..
*.*...
*....
*.*...
*.*.*..
*.*.*.*.
参考答案:
代码语言:javascript复制#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - i 1; j )
{
printf("* ");
}
for (j = 0; j < i; j )
{
printf(" ");
}
printf("n");
}
for (i = 0; i < n 1; i )
{
for (j = 0; j < 1 i; j )
{
printf("* ");
}
for (j = 0; j < n - i; j )
{
printf(" ");
}
printf("n");
}
}
return 0;
}
箭形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的箭形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20)。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的箭形。
输入:
代码语言:javascript复制2
输出:
代码语言:javascript复制 *
**
***
**
*
输入:
代码语言:javascript复制3
输出:
代码语言:javascript复制 *
**
***
****
***
**
*
参考答案:
代码语言:javascript复制#include <stdio.h>
int main()
{
int n = 0;
int i = 0,j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - i; j )
{
printf(" ");
}
for (j = 0; j < 1 i; j )
{
printf("*");
}
printf("n");
}
for (i = 0; i < n 1; i )
{
for (j = 0; j < i; j )
{
printf(" ");
}
for (j = 0; j < n 1 - i; j )
{
printf("*");
}
printf("n");
}
}
return 0;
}
常规做法并不一定是最简单的方法
反斜线形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的反斜线形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示输出的行数,也表示组成反斜线的“*”的数量。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的反斜线。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制*...
.*..
..*.
...*
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制*....
.*...
..*..
...*.
....*
参考答案:
代码语言:javascript复制//方法1:套模板
#include <stdio.h>
int main()
{
int n = 0;
int i = 0,j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < n - 1 - i; j )
{
printf(" ");
}
printf("n");
}
}
return 0;
}
代码语言:javascript复制//方法2:找规律
#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n; j )
{
if (i == j)
printf("*");
else
printf(" ");
}
printf("n");
}
}
return 0;
}
正斜线形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的正斜线形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示输出的行数,也表示组成正斜线的“*”的数量。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的正斜线。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制...*
..*.
.*..
*...
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制....*
...*.
..*..
.*...
*....
参考答案:
代码语言:javascript复制//方法1:套模板
#include <stdio.h>
int main()
{
int n = 0;
int i = 0,j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n - 1 - i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < i; j )
{
printf(" ");
}
printf("n");
}
}
return 0;
}
代码语言:javascript复制//方法2:找规律
#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n; j )
{
if (i j == n - 1)
printf("*");
else
printf(" ");
}
printf("n");
}
}
return 0;
}
X形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的X形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的X形图案。
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制*...*
.*.*.
..*..
.*.*.
*...*
输入:
代码语言:javascript复制6
输出:
代码语言:javascript复制*....*
.*..*.
..**..
..**..
.*..*.
*....*
参考答案:
代码语言:javascript复制方法一套模板很繁琐,我尝试做了一下,我一开始是照着偶数排列去做的,后面发现奇数和偶数还不一样,我又分成了奇数偶数两块,偶数部分很轻松,但是奇数部分重叠了一列,我试图用continue语句跳过这一列,但我学艺不精,没搞定,呜呜呜,孩子哭了,还请看到的大佬帮我改一下
//方法1:套模板(有个bug)
//这个题可以拆分成上下左右四大部分,每一部分再分成三小部分,也就是需要12个printf("");语句,其中带有for循环的有8个,程序如下。
#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
//奇数
if (n % 2 != 0)
{
for (i = 0; i < n / 2; i )
{//左上
for (j = 0; j < i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < n / 2 - i; j )
{
printf(" ");
}
//右上
for (j = 0; j < n / 2 - i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < i; j )
{
printf(" ");
}
printf("n");
}
for (i = 0; i < n / 2 1; i )
{//左下,其实就是右上,复制粘贴下就ok
for (j = 0; j < n / 2 - i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < i; j )
{
printf(" ");
}
//右下,其实就是左上,复制粘贴下就ok
for (j = 0; j < i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < n / 2 - i; j )
{
printf(" ");
}
printf("n");
}
}
//偶数
if(n%2==0)
{
for (i = 0; i < n / 2; i )
{//左上
for (j = 0; j < i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < n / 2 - 1 - i; j )
{
printf(" ");
}
//右上
for (j = 0; j < n / 2 - 1 - i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < i; j )
{
printf(" ");
}
printf("n");
}
for (i = 0; i < n / 2; i )
{//左下,其实就是右上,复制粘贴下就ok
for (j = 0; j < n / 2 - 1 - i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < i; j )
{
printf(" ");
}
//右下,其实就是左上,复制粘贴下就ok
for (j = 0; j < i; j )
{
printf(" ");
}
printf("*");
for (j = 0; j < n / 2 - 1 - i; j )
{
printf(" ");
}
printf("n");
}
}
}
return 0;
}
代码语言:javascript复制//方法2:找规律
#include <stdio.h>
int main()
{
int n = 0;
int i = 0; int j = 0;
while (scanf("%d", &n) != EOF)
{
for (i = 0; i < n; i )
{
for (j = 0; j < n; j )
{
if (i == j)
printf("*");
else if (i j == n - 1)
printf("*");
else
printf(" ");
}
printf("n");
}
}
return 0;
}
模版的局限性
做到后面两题的时候我发现,图案很难分割成有规律的三角形图案,所以我发现此模版的适用范围只能是“由连续的”三角形排列“或者可以分割成连续的“三角形”的图案的题目,其他的还是得找规律。
“空心”正方形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的“空心”正方形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(3~20),表示输出的行数,也表示组成正方形边的“*”的数量。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的“空心”正方形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制* * * *
* *
* *
* * * *
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制* * * * *
* *
* *
* *
* * * * *
参考答案:
代码语言:javascript复制#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 0; i < n; i )
{
for (j = 0; j < n; j )
{
if (i == 0 || i == n - 1)
printf("* ");
else if (j == 0 || j == n - 1)
printf("* ");
else
printf(" ");
}
printf("n");
}
}
return 0;
}
“空心”三角形图案
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的“空心”三角形图案。
输入描述:
代码语言:javascript复制多组输入,一个整数(3~20),表示输出的行数,也表示组成三角形边的“*”的数量。
输出描述:
代码语言:javascript复制针对每行输入,输出用“*”组成的“空心”三角形,每个“*”后面有一个空格。
输入:
代码语言:javascript复制4
输出:
代码语言:javascript复制*.......
*.*.....
*...*...
*.*.*.*.
输入:
代码语言:javascript复制5
输出:
代码语言:javascript复制*.........
*.*.......
*...*.....
*.....*...
*.*.*.*.*.
参考答案:
代码语言:javascript复制#include <stdio.h>
int main()
{
int n = 0;
int i = 0, j = 0;
while (~scanf("%d", &n))
{
for (i = 1; i < n 1; i )
{
for (j = 1; j < n 1; j )
{
if ((i == j) || (j == 1) || (i == n))
{
printf("* ");
}
else
{
printf(" ");
}
}
printf("n");
}
}
return 0;
}