應網友要求, 這次把中空凌形說明和原始碼放上來..

由於說明過長,在看說明時,

建議先把圖形長相先畫在紙上,避免不便閱讀。

現在我們考慮以下圖形。

 03.PNG

如圖所示,我將圖形分成 A 部份和 B 部份分別做分析
而使用者輸入 9 時,凌形高度的對半剛好就等於9
為方便說明,此處我分析時,9 到時會用 n 代替
現在只考慮 A 部份(為1~n行)..

1. 考慮 A 部份之紅色三角型部份(即第一個數字前之空白數)
觀查行數和空白數的關係,我們可以觀查出下列規則
第 1 行-> 8 個空白
第 2 行-> 7 個空白
第 3 行-> 6 個空白
...
第 i 行 -> n-i 個空白

第一段的 code 出來了

        // A Part   
        for(i=1; i<=n; i++){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" "); 
                ..........
        }

2. 印出第一個數字部份

第 1 行 -> 印出 1
第 2 行 -> 印出 2
....
第 i 行 -> 印出 i

接著又可以寫下來..

        // A Part   
        for(i=1; i<=n; i++){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" ");

                // 2. 印出 第1個數字
                printf("%d", i);
 
                ..........
        }

3. 考慮 A 部份之亮綠色三角型部份(即第二個數字前之空白數)

第 1 行-> 0 個空白(事實上這行可以不用考慮,因為就算印出100個空白,也不會印出第二個數字)
第 2 行-> 1 個空白
第 3 行-> 3 個空白
.....
第 i 行 -> 2i-3 個空白

關於這部份, 有人說看不出規則性,
於是在此提供下列方法

假設第 x 行印出 y 個空白
我們便可假設 y = ax + b... (1)式
現在要求的是 a, b 值
代入第2行有1個空白 -> x=2, y=1 , 代入 (1) 式 -> 1 = 2a+b.... (2)式
代入第3行有3個空白 -> x=3, y=3 , 代入 (1) 式 -> 3 = 3a+b.... (3)式
接著解 (2), (3) 式連立, 可以得到 a=2, b=-3
即 y=2x-3
於是可以得到以下結論:
第 x 行有 2x-3 個空白數, 即 第 i 行有 2i-3 個空白數
這種連立方程式的方式畫*問題幾乎都可這麼分析

於是第3段code 出來了..

        // A Part   
        for(i=1; i<=n; i++){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" ");

                // 2. 印出 第1個數字
                printf("%d", i);
 
  
                // 3. 印出 第2個數字 之前的空白數
                for(j=1; j<=2*i-3; j++) printf(" ");
                ........

        }

4. 印出第二個數字並換行
第 1 行 -> 不印數字, 換行
第 2 行 -> 印出 2, 換行
第 2 行 -> 印出 3, 換行
...
第 i 行 -> 印出 i, 換行

在這裡可以發現一個規律, 和第2點很像
只是第 1 行只印1個數字1,不印第二個數字
其它的都是第 i 行印出 i, 於是用 if-else 控制後如下所述..

        // A Part   
        for(i=1; i<=n; i++){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" ");

                // 2. 印出 第1個數字
                printf("%d", i);
 
                
               
// 3. 印出 第2個數字 之前的空白數
                for(j=1; j<=2*i-3; j++) printf(" ");

                // 4. 印出第2個數字, 並予以換行
                // 如果數字是 1 的話就不再印數字,直接換行
                if(i==1) printf("\n");
                else printf("%d\n", i);
        }

到底為止,以上 A part 部份已完成,
接下來 B part 部份與 A part 極為相似

5. B part  部份

有心者請再從 step1~step4 重覆一次步驟
發現唯一有差的是 i 的變化..
數字到9後,又從8, 7, 6...., 1 一路降一
於是B part 外回圈的 i 便設成

for(i=n-1; i>0; i--)

接著其它的分析都一樣, 甚至連紅色三角形、綠色三角形與 i 值的關係都一樣
於是 B Part 的 code 便長這樣...

     // B Part   
     for(i=n-1; i>=; i--){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" ");

                // 2. 印出 第1個數字
                printf("%d", i);
 
                
               
// 3. 印出 第2個數字 之前的空白數
                for(j=1; j<=2*i-3; j++) printf(" ");

                // 4. 印出第2個數字, 並予以換行
                // 如果數字是 1 的話就不再印數字,直接換行
                if(i==1) printf("\n");
                else printf("%d\n", i);
        }

6. A part 與 B part 結合
最後 A part 與 B part 結合後
完整程式碼便如下所示...


#include <stdio.h>
int main()
{
        int i, j, n;
        printf("請輸入n(n<10):");
        scanf("%d", &n);

        // A Part, 上半段
        for(i=1; i<=n; i++){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" ");

                // 2. 印出 第1個數字
                printf("%d", i);
 
                
               
// 3. 印出 第2個數字 之前的空白數
                for(j=1; j<=2*i-3; j++) printf(" ");

                // 4. 印出第2個數字, 並予以換行
                // 如果數字是 1 的話就不再印數字,直接換行
                if(i==1) printf("\n");
                else printf("%d\n", i);
        }

     // B Part, 下半段
     for(i=n-1; i>=; i--){ 
// 共 n 行
                // 1. 印出 第1個數字 之前的空白數
                for(j=1; j<=n-i; j++) printf(" ");

                // 2. 印出 第1個數字
                printf("%d", i);
 
                
               
// 3. 印出 第2個數字 之前的空白數
                for(j=1; j<=2*i-3; j++) printf(" ");

                // 4. 印出第2個數字, 並予以換行
                // 如果數字是 1 的話就不再印數字,直接換行
                if(i==1) printf("\n");
                else printf("%d\n", i);
        }
        return 0;
}

以上,分析至此
再次強調,方法非唯一,
這種分析法執行速度並不算快
但所有的圖形問題,也跑不過這種分析方式

感謝各位收聽!!

arrow
arrow
    全站熱搜

    Edison 發表在 痞客邦 留言(1) 人氣()