起因:
前一阵子做了一道题:
从控制台用‘*’打印正空心6边形。
我看完之后郁闷了半天
,控制台字符是竖长的,增么也不可能呈现出正多边形的效果过,加空格的话,一旦打印变数边长效果也不明显,后来一想不对,应该就是边多长就打印几个‘*’。其实当时有点紧张没写完,也没分析下,用了个笨方法,今天用个简单的,我们先分析一下问题。
分析:
对于从控制台打印,说白了,我们需要控制‘ ’(空格)和‘*’(星)何时打印,打印多少。我们需要控制的地方主要有3处。
B
* * * * *
A * *
* *
* *
* C *
* *
* *
A * *
* * * * *
B
(1)B处,因为是一行一行打印,所以要单独控制第一行和最后一行的打印,其他行肯定每次打印都只有两颗星。
(2)A处,每一行打印时,控制台左边到第一颗‘*’(星)之间要补充多少‘ ’(空格)。
(2)C处,每一行打印时,除了第一行和最后一行两个边,其他边两颗星之间需要补充多少‘ ’(空格)。
控制台就是一个大矩阵,打印数量之间肯定有数量关系(废话
)。可以把这个打印抽象成两个函数(数学上的函数,不是写程序里说的那个函数),者3个更或者4个,当然我们说最简单的2个的——就是第一行和最后一行一个函数,中间的一个函数。
思路:
我想单独用变量行号控制(当然还有边长,不过一旦确定是就不变了,所以是个常数),但对于补充的空格边上是先减后增,中间是先增后减,要用一个变量控制的话我们肯定想到绝对值函数(y=|x|),特殊就特殊在函数有一个非常明显的拐点,且以此点做垂直于横轴的线,将左右两部分图形对称,通过合理的控制它,我们就能实现用一个变量在某个特定的值前后对称增减了。
设行号为L,第一行行号为0,L属于非负整数,正六边形边长为N,N属于非负整数。
对于在控制台上打印,边长为N的正六边形要打印 2 * N - 1 行。
控制台左边到第一颗星之间要补充|N - L - 1|个空格(注意两旁的绝对值符号)。
除第一行和最后一行,中间每行在两个‘*’(星)之间要补充N + (N - 2) * 2 - ((|L + 1 - N|) * 2)个空格,化简一下3 * N - 4- ((|L + 1 - N|) * 2)。
好了,我们有了需要的式子。
实现:
/*************************************
*函 数:void prt(char c, int count) *
*参 数:指定字符,打印数量 *
*功 能:打印指定数量的指定字符 *
*返 回:无 *
*************************************/
void prt(char c, int count)
{
while(count--)
{
printf("%c", c);
}
}
/*********************
*函 数:int main() *
*参 数:无 *
*功 能:主函数 *
*返 回:0 *
*********************/
int main()
{
int N, L = 0;
scanf("%d", &N);
//循环打印每一行
for(; L < 2 * N - 1; L++)
{
prt(' ', abs(N - L - 1)); //补充控制台到每行第一颗星的空格
//第一行和最后一行单独处理
if(0 == L || L == 2 * N - 2)
{
prt('*', N);
}
else
{
prt('*', 1);
//prt(' ', N + (N - 2) * 2 -(abs(L + 1 - N) * 2));
prt(' ', 3 * N - 4 -(abs(L + 1 - N) * 2)); //补充中间的空格
prt('*', 1);
}
puts(""); //换行
}
return 0;
}
总结:
第一次我一上来就写,分了3段,用了3个变量,现在分析一下之后,找到数量关系貌似简单了不少,不到20行(去掉花括号)就搞定了,以后一定要先分析一下再做,能省不少功夫。