C語言程序設計100例之(28):直線蛇形陣

例28        直線蛇形陣

問題描述編程

編寫程序,將天然數一、二、…、N2按蛇形方式逐個順序存入N階方陣。例如,當N=3和N=4時的直線蛇形陣以下圖1所示。數組

 

圖1  直線蛇形陣3d

輸入格式blog

一個正整數n(1≤n≤20)。it

輸出格式io

N階知足要求的直線蛇形方陣。輸出時共n行,每行n個數,每一個數佔4列。編譯

輸入樣例變量

4循環

輸出樣例遍歷

  13  14  15  16

  12  11  10   9

   5   6   7   8

   4   3   2   1

        (1)編程思路。

         從圖1能夠看出,直線蛇形陣的構造是從最底行(row=N-1)向最頂行(row=0)進行的。每行的填寫在兩種方式間切換,一種方式是從右到左順序(即for(j=n-1;j>=0;j--) )依次遞增1填寫,稱爲方式1;另外一種方式是從左到右順序(即for(j=0;j<=n-1;j++) )依次遞增1填寫,稱爲方式2。

         程序中定義一個變量k來標誌這兩種方式,k初始值爲0,表示採用方式1,當前行按方式1填寫完後,改變k的值,使其等於1,表示採用方式2,當前行按方式2填寫完後,再改變k的值,使其等於0。

         (2)源程序。

#include<stdio.h>

int main()

{

    int a[20][20]={0},n;

    scanf("%d",&n);

         int i,j,k=0,t=1;

         for(i=n-1;i>=0;i--)                        // 遍歷行

         {

                   if(k==0)                                 // 從右到左順序依次遞增1存數組元素

                   {

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

                                     a[i][j]=t++;

                            k=1;

                   }

                   else                                       // 從左到右順序依次遞增1存數組元素

                   {

                            for(j=0;j<=n-1;j++)

                                     a[i][j]=t++;

                            k=0;

                   }

         }

    for (i=0;i<n;i++)

    {

           for (j=0;j<n;j++)

                    printf("%4d",a[i][j]);

           printf("\n");

    }

    return 0;

}

習題28

28-1  斜線蛇形陣

問題描述

編寫程序,將天然數一、二、…、N2按蛇形方式逐個順序存入N階方陣。例如,當N=3和N=4時的方陣以下圖2所示。

 

圖2  斜線蛇形陣

輸入格式

一個正整數n(1≤n≤20)。

輸出格式

N階知足要求的斜線蛇形方陣。輸出時共n行,每行n個數,每一個數佔4列。

輸入樣例

5

輸出樣例

  15    16    22    23    25

   7    14    17    21    24

   6     8    13    18    20

   2     5     9    12    19

   1     3     4    10    11

        (1)編程思路。

        觀察圖2所示的斜線蛇形陣可知,方陣在逐個填數構造的過程當中,是沿兩種斜線進行的,一種是斜向下,一種是斜向上,如圖3(a)所示。

        設當前已填入數字的位置的行號爲row(row在0~n-1之間),列號爲col(col也在0~n-1之間)。若按斜向下填寫,則下一位置爲row++、col++ ;若按斜向上填寫,則下一位置爲row--、col--。因爲下一位置可能超出方陣的邊界,所以有時須要調整。調整有4種狀況,下面分別進行說明。

圖3  斜線蛇形陣的構造示意圖

        斜向下填寫時,會出現兩種狀況:

        1)超過了底行的位置(即row==n),如圖3(b)所示,3填寫好後,下一個數4的計算位置越界了,此時進行調整,方法爲列col不變,row減1(即 row--)。

        2)超過最右列的位置(即col==n),如圖3(c)所示,15填寫好後,下一個數16的計算位置越界了,此時進行調整,方法爲col--、row=row-2。

        一種特例,10填寫好後,下一個數11的計算位置,行和列都越界了,但處理方法同列越界,所以在程序中應先處理col==n的狀況,再處理row==n的狀況。這樣對於這種特例,因爲處理了col==n後,row減了2,不會越界,所以不會再處理row==n的狀況。

        斜向上填寫時,也會出現兩種狀況:

        1)超過了首行的位置(即row==-1),如圖3(d)所示,13填寫好後,下一個數14的計算位置越界了,此時進行調整,方法爲row++、col=col-2。

         2)超過最左列的位置(即col==-1),如圖3(e)所示,6填寫好後,下一個數7的計算位置越界了,此時進行調整,方法爲row不變、列號加1(即col++)。

         一種特例,在如圖3(f)所示的3階方陣中,6填寫好後,下一個數7的計算位置,行和列都越界了,其處理方法同行越界,所以在程序中應先處理row==-1的狀況,再處理col==-1的狀況。這樣對於這種特例,因爲處理了row==-1後,col加了2,不會越界,所以不會再處理col==-1的狀況。

         每次進行越界調整填數後,填數的方向也會發生變化。所以,可設置一個變量up,當up=1時,表示斜向上填數;up=0時,表示斜向下填數。

         初始化時,令up=一、row=n-一、col=0、 num=1;在當前位置填上1(即a[row][col]=1),以後進行循環,直到n*n個數填寫完畢。循環中,老是先按up的方向,肯定下一個位置,而後填上相應的數。例如,1向上到2,越界,調整便可,如圖3(e)所示。

        (2)源程序。

#include<stdio.h>

int main()

{

    int a[20][20]={0},n;

    scanf("%d",&n);

    int up=1;

    int row=n-1;

    int col=0;

    int num=1;

    a[row][col]=num++;

    while (num<=n*n)

    {

        if (up) {  row--; col--;}

        else    { row++; col++;}

        if (row==-1)                      // 超過首行的位置

        {    row++; col=col+2;  up=1-up;    }

        if (col==n)                       // 超過最右列的位置

        {    row=row-2; col--;   up=1-up;     }

        if (row==n)                       // 超過底行的位置

        {   row--;   up=1-up;       }

        if (col==-1)                     // 超過最左列的位置

        {        col++;   up=1-up;     }

        a[row][col]=num++;

    }

    for (int i=0;i<n;i++)

    {

           for (int j=0;j<n;j++)

                    printf("%4d",a[i][j]);

           printf("\n");

    }

    return 0;

}

        若將程序中的up的初始值設定爲0,即開始斜向下填寫。從新編譯並執行以上程序,則獲得以下所示的結果。

5

  11    19    20    24    25

  10    12    18    21    23

   4     9    13    17    22

   3     5     8    14    16

   1     2     6     7    15

28-2  對稱方陣

問題描述

圖4所示爲兩個7階對稱方陣,形象起見,可將(a)方陣稱爲環形對稱方陣,(b)方陣稱爲三角形對稱方陣。

 

圖4 對稱方陣

輸入格式

兩個正整數n(1≤n≤20)和k(k爲1或2)。

輸出格式

N階知足要求的對稱方陣。若k=1,輸出環形對稱方陣,k=2,輸出三角形對稱方陣。輸出時共n行,每行n個數,每一個數佔3列。

輸入樣例1

5 1

輸出樣例1

  0  1  1  1  0

  1  0  2  0  1

  1  2  0  2  1

  1  0  2  0  1

  0  1  1  1  0

輸入樣例2

7 2

輸出樣例2

  0  1  2  3  2  1  0

  1  0  1  2  1  0  1

  2  1  0  1  0  1  2

  3  2  1  0  1  2  3

  2  1  0  1  0  1  2

  1  0  1  2  1  0  1

  0  1  2  3  2  1  0

        (1)編程思路。

        1)生成如圖4(a)所示的環形對稱方陣的方法。

        設方陣中元素的行號爲row,列號爲col。爲方便見,row和col均從1開始計。

        方陣的主對角線(即row==col)和次對角線(即row+col==n+1)的各元素均賦值「0」。

        按兩條對角線把方陣可分紅上部、左部、右部與下部4個區,如圖5所示。

 

圖5  環形對稱方陣的四個分區

四個分區的賦值方式爲:

上部按行號row賦值,即if (row+col<n+1 && row<col)   a[row][col]=row。

下部按表達式n+1-row賦值,即if (row+col>n+1 && row>col)  a[row][col]=n+1-row。

左部按列號col賦值,即if (row+col<n+1 && row>col)  a[row][col]=col。

右部按表達式n+1-col賦值,即if (row+col>n+1 && row<col)  a[row][col]=n+1-col。

2)生成如圖4(b)所示的三角形對稱方陣的方法。

令m=(n+1)/2,按圖6(a)所示分紅4個區。

圖6  三角形對稱方陣的四個分區

       仔細分析這個四個分區的元素值與行號、列號的關係,並參照圖6(b)所示的7階對稱方陣各元素的值,可概括出:

       左上區(row<=m && col<=m)與右下區(row>m && col>m)參照主對角線賦值:

            a[row][col]=abs(row-col) 。

       右上區((row<=m && col>m)與左下區(row>m && col<=m)參照次對角線賦值:

           a[row][col]= abs(row+col-n-1)。

        (2)源程序。

#include <stdio.h>

#include <math.h>

int main()

{

    int n,k,row,col,a[21][21]={0};

    scanf("%d%d",&n,&k);

    if (k==1)

    {

       for (row=1; row<=n; row++)

       for (col=1; col<=n; col++)

            {

                 if (row==col || row+col==n+1)

                     a[row][col]=0;           // 方陣對角線元素賦值

               if (row+col<n+1 && row<col)

                    a[row][col]=row;         // 方陣上部元素賦值

                if (row+col<n+1 && row>col)

                    a[row][col]=col;         // 方陣左部元素賦值

                 if (row+col>n+1 && row>col)

                    a[row][col]=n+1-row;     // 方陣下部元素賦值

                if (row+col>n+1 && row<col)

                    a[row][col]=n+1-col;     // 方陣右部元素賦值

            }

    }

    else

    {

        int m=(n+1)/2;

        for (row=1; row<=n; row++)

        for (col=1; col<=n; col++)

             {

                      if ((row<=m && col<=m) || (row>m && col>m))

                          a[row][col]=abs(row-col);         // 方陣左上部與右下部元素賦值

                    if ((row<=m && col>m) || (row>m && col<=m))

                         a[row][col]=abs(row+col-n-1);     // 方陣右上部與左下部元素賦值

             }

     }

    for (int i=1;i<=n;i++)

    {

           for (int j=1;j<=n;j++)

                    printf("%3d",a[i][j]);

           printf("\n");

    }

    return 0;

}

28-3 螺旋下三角陣

問題描述

編寫程序,將天然數一、二、…、(1+N)*N/2按螺旋方式逐個順序存入N階下三角矩陣。例如,當N=3和N=4時的矩陣以下圖7所示。

 

圖7  螺旋下三角陣

輸入格式

一個正整數n(1≤n≤20)。

輸出格式

N階知足要求的螺旋下三角陣。輸出時每一個數佔4列。

輸入樣例

5

輸出樣例

   1   2   3   4   5

  12  13  14   6

  11  15   7

  10   8

   9

        (1)編程思路

        螺旋下三角陣的構造能夠當作由向右填充(行號不變、列號加1,即col++)、斜向下填充(row++、col--)和向上填充(行號減一、列號不變,即row--)三個子過程不斷交替完成的。

         例如,圖8所示的3階螺旋下三角陣能夠當作由向右填充(一、二、3),斜向下填充(四、5)和向上填充(6)這3個子過程完成的。4階螺旋下三角陣能夠當作由向右填充(一、二、三、4),斜向下填充(五、六、7)、向上填充(八、9)和向右填充(10)這4個子過程完成的。

        n階螺旋下三角陣能夠當作由n個子過程完成,每一個子過程爲向右填充、斜向下填充和向上填充這三種中的一種,用變量direction來表示,其取值爲0、1或2,0表示向右填充,1表示斜向下填充,2表示向上填充。每一個子過程結束後,切換填充方向,方式爲:

             direction=(direction+1)%3; 

        n個子過程當中,第1個子過程填寫n個數,第2個子過程填寫n-1個數,…,最後一個子過程填寫1個數。所以,程序整體寫成一個二重循環,描述爲:

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

        {      

              for (j=1;j<=i;j++)

             {

                  按填充方向,填充相應數據

              }

              direction=(direction+1)%3;          // 切換填充方向

         }   

        初始時,注意row=0,col=-1,這樣向右col++後,col爲0,正好填在第1個位置。

(2)源程序。

#include <stdio.h>

int main()

{

    int a[20][20]={0},row,col,i,j,n,num;

    int direction=0;

    scanf("%d",&n);

    row=0; col=-1; num=1;

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

    {

        for (j=1;j<=i;j++)

        {

              switch(direction)

              {

                      case 0:col++;break;        // 向右填充

                     case 1:row++;col--;break;  // 斜向下填充

                     case 2:row--;break;        // 向上填充

               }

              a[row][col]=num++;

        }

        direction=(direction+1)%3;          // 切換填充方向

    }

    for(row=0;row<n;row++)

    {

         for(col=0;col<n-row;col++)

                printf("%4d",a[row][col]);

         printf("\n");

    }

    return 0;

}

相關文章
相關標籤/搜索