1038?打印图案
时间限制:1000MS? 代码长度限制:10KB 提交次数:4316 通过次数:2828
题型: 编程题???语言: G++;GCC
Description
由键盘输入正数n(n<10),要求输出如下中间数字为n的菱形图案。
输出格式
菱形右边不留多余空格
输入样例
4
输出样例
1
121
12321
1234321
12321
121
1
耗时两个小时左右,一开始胡乱敲了一通,反复改着不明所以的变量。以为做出来了,结果发现不知道为什么左边多出了空格。
果断放弃,第二天理了一下思路,很快就做出来了。
这一类题思路一定要清晰,我的想法是先打印出一个平躺的房屋型,然后用if选择那些要输出,哪些填空格。
我分析了数字关系,发现可以利用行和列大小之间的关系。
我让行i:12345=h:12321,j:12345=hh:12321=H:32123。只要当h>=H的时候输出就可以了
打印数字的时候,我一开始是想h*hh/n,后来发现边缘数处理不了。
就让菱形正中间当坐标原点,计算离原点的距离,结果通过了。
下面是我的代码:
#include<stdio.h>
#include<math.h>
int main()
{
int i, j,H,h,n,hh,N;
scanf_s("%d", &N);
n = N - 1;
for (j = 1; j < 2*n+2; j++)
{
for (i = 1; i < 2*n+2; i++)
{
if (j <= n + 1)
{
H = n + 2 - j;
}
else
{
H = -n + j;
}
if (i <= n + 1)
{
h = i;
}
else
{
h = 2 * n + 2 - i;
}
if (j <= n + 1)
{
hh = j;
}
else
{
hh = 2 * n + 2 - j;
}
if (h < H)
{
printf(" ");
}
else
{
printf("%d",-(n+1)+h+hh );
}
}
printf("\n");
}
}
下面是标准答案
#include<stdio.h>
#define abs(x) ((x)>0?(x):-(x))//定义绝对值
main()
{ int n,i,j;
scanf("%d",&n);//假如n=4
n--;
for(i=-n;i<=n;i++)//i=-3-2-10123,abs(i)=3210123
{ for(j=0;j<abs(i);j++) printf(" ");//每i的j<3,2,1,0,1,2,3时打空格
for(j=-(n-abs(i));j<=n-abs(i);j++)//(n-abs(i))=0123210,然后打印1,2,3,2..个数字
printf("%d",n+1-abs(j)-abs(i));
printf("\n");
}
}
注解是我自己写的,当我看到答案时,我虽然看不懂,但大受震撼。??
仔细一想,这种单增然后突然单减,还要求对称的变量,用绝对值abs确实是最优解,能节省很多的代码量。
反推编写代码的思路,依靠绝对值的对称,做出了先减后增的abs(i)(大小大),根据该变量大小设置空位置(大小大),打完空格后,用n-abs(i)又设置了输出个数(小大小),最后计算n+1(定为坐标点)与周围元素的距离,打印该距离。
n-abs(i)虽然0123210,但输出的个数却是1234321,这是因为j是<=,满足了条件就会打印。没有设置输出位置而是设置在空格后的输出个数,省去了很多代码量。
|