一、
首先从题目入手,我们将探讨该题的 思路 与 不断优化 的解答方式
BC75 数字三角形
描述
KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用数字组成的数字三角形图案。
输入描述:
多组输入,一个整数(3~20),表示数字三角形边的长度,即数字的数量,也表示输出行数。
输出描述:
针对每行输入,输出用数字组成的对应长度的数字三角形,每个数字后面有一个空格。
示例
输入:
4
复制输出:
1 1 2 1 2 3 1 2 3 4
二、最初的想法
数组题目,就是观察数据的排列逻辑,因此,本着初始化-->特殊元素赋值-->打印的步骤,去完成了第一次的代码书写
上码:
#include <stdio.h>
int main() {
int n = 0;
int i = 0;
int j = 0;
char arr[20][40] = { 0 };
while(scanf("%d",&n)==1)
{
getchar();
for(i = 0; i < n; i++)
{
for(j = 0; j < 2 * n; j++)
{
arr[i][j] = ' '; //初始化
if(j == 2 * i) //特殊元素赋值
{
int m = 0;
for( m = i; m < n; m++)
{
arr[m][j] = i + 1;
}
}
if(arr[i][j] == ' ') //打印
{
printf(" ");
}
else {
printf("%d",arr[i][j]);
}
}
putchar(10);
}
}
return 0;
}
运行结果:
输入:8
1
2
3
4
5
6
7
8
输入:4
1
2
3
4
输入:3
1
2
3
并没有达到数字三角形的目的。通过观察输出,发现本该打印数字的位置打印成了空格。于是思考是赋值出现问题。
通过观察赋值阶段:
arr[i][j] = ' '; //初始化
if(j == 2 * i) //特殊元素赋值
{
int m = 0;
for( m = i; m < n; m++)
{
arr[m][j] = i + 1;
}
发现当进入for( m = i; m < n; m++)该循环的时候,每次进入,都会将元素重新赋值为0
不同于这个
for(j = 0; j < 2 * n; j++)
{
arr[i][j] = ' '; //初始化
//赋值
arr[i][0] = '*';
arr[i][2*i] = '*';
if(i == n-1 && j % 2 == 0)
{
arr[i][j] = '*';
}
//打印
printf("%c",arr[i][j]);
}
这个只是对当前的一个元素进行筛查赋值,重新赋值。并没有像上边的代码一样,对多个元素赋值。
二、
发现问题之后,进行首次修改:
int main() {
int n = 0;
int i = 0;
int j = 0;
char arr[20][40] = { 0 };
while (scanf("%d", &n) == 1)
{
getchar();
for (i = 0; i < n; i++)
{
for (j = 0; j < 2 * n; j++)
{
arr[i][j] = ' '; //初始化
}
}
for (i = 0; i < n; i++)
{
for (j = 0; j < 2 * n; j++)
{
//修改
if (j == 2 * i)
{
int m = 0;
for (m = i; m < n; m++)
{
arr[m][j] = i + 1;
}
}
//打印
if (arr[i][j] == ' ')
{
printf(" ");
}
else {
printf("%d", arr[i][j]);
}
}
putchar(10);
}
}
return 0;
}
//此代码是先初始化,再对数据进行修改,打印。可得到正确的数字三角形。
但是仍然存在弊端,代码过长,过于冗余。因此另辟蹊径,尝试用简单的代码去解题
三、优化思路与代码
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 <= i; j++)
{
printf("%d ", j+1); //将数字和空格看成一个整体打印
}
printf("\n");
}
}
return 0;
}
比较复杂的图像,先不要尝试用数组解题,先尝试直接解题。
思路:
将军莫虑,且看此图!
列出特殊元素的位置坐标之后,仔细观察特殊元素的行列关系 ((1.2)修改为(1,1))
发现 j 都是从0开始,j 始终小于等于 i ,特殊元素的数值是 j + 1
因此可以这样赋值
for (j = 0; j <= i; j++)
{
printf("%d ", j+1); //将数字和空格看成一个整体打印
}
从而得到了最终版本。
四、总结
对于略微复杂的数组题目,可以先不着急利用数组赋值进行解题。可以先画好图之后,写出坐标,观察坐标 i j 的关系去解题,从而确立循环该如何书写。
步骤:画图、 写坐标、 观察 j i 的关系、 观察数据和元素的关系