打印菱形

    接着昨天的倒計時,今天寫了一個菱形的算法。題目:輸入一個菱形的高n(必須爲奇數),即行數,也是正中間行的星號個數,打印用星號組成的菱形。如下圖,高爲9的菱形:


    看到此題,想到的第一個方法就是先打印上半部分,再打印下半部分。這個仔細觀察,就能找到規律,寫出來不難。後來想能否不分上下部分,直接for循環,從1到n,一次性全部打印出來。主要是想把上下部分的打印程序整合在一起,相當於都調用同一個帶參數的函數即可。最後也沒想到什麼好方法,就從每行的前半部分空格和後半部分星號開始思路。

    前半部的空格都好應付。空格個數在上半部分從n/2減到0,再從下半部分的0增加到n/2。空格個數與行數i的關係分別是:(n+1)/2-i和i-(n+1)/2。

    後半部的星號個數都是上半部分每行加2,加到n;然後下半部分逐行再減2,減到1。經過分析,星號個數與行數i的關係分別是:2*i-1和n-2*(i-(n+1)/2)。主要是下半部分的公式看上去比較複雜,其實可以從兩個角度來理解(設m=(n+1)/2,即正中間的行數。)。

    一、垂直對稱法。這裏每行都可以理解爲打印n個字符,中間是星號,兩邊是同等個數的空格,即對稱於豎直的對角線,也就是垂直對稱。上面已分析出空格數與行數的關係是i-m,所以中間的星號是總的字符數n,再減去兩邊的空格數2*(i-m),即n-2*(i-m)。

    二、疊加相減法。每行中,前面空格數加上後面星號數的打印總數s,是不是從n開始在逐行遞減(以-1爲增量)?每行打印總數s與n,是不是存在一個這麼的關係:s=n-(i-m),即n減去每行的空格數?星號總數,也就是打印總數s減去每行的空格數了,即s-(i-m)=n-2*(i-m)。

    代碼如下:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <windows.h>

int main(int argc, char **argv) 
{
	UCHAR n=9;
	UCHAR m,a,b,i,j;

	if(n%2 == 0)
		return -1;
	m=(n+1)/2;
	for(i=1; i<=n; i++){
		if(i < m){
			a = m-i;
			b = 2*i -1; //a+b = m+i-1
		}else{
			a = i-m;
			b = n-2*(i-m); //a+b = n-(i-m)
		}
		for(j=1; j<=a; j++)
			printf(" ");
		for(j=1; j<=b; j++)
			printf("*");
		printf("\n");
	}
	
	system("pause");
}


    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章