C問題---矩陣輸出問題

---------------------------------
典型例題 33:C問題---矩陣輸出問題
---------------------------------
     1    #include <iostream>
     2    #include <cstring>
     3   
     4    using namespace std;
     5    /*
     6    *********************************************
     7    $ ./a.out
     8    Please Input The N = 6
     9    n = 6
    10    1    2    9    10    25    26   
    11    4    3    8    11    24    27   
    12    5    6    7    12    23    28   
    13    16    15    14    13    22    29   
    14    17    18    19    20    21    30   
    15    36    35    34    33    32    31
    16    *********************************************
    17    */   
    18    int matrix_print(int n)
    19    {
    20       int a[n][n];
    21       bzero(a,n*n*sizeof(int));
    22       int tag = 0;
    23       int count = 2;
    24      
    25       a[0][0] = 1;
    26       for(int step = 3; step <= 2*n-1 ; step +=2)
    27       {   
    28            int i,j;
    29            if(0 == tag)//順時針
    30            {
    31                for (i = 0; i < step/2; ++i)
    32                {
    33                    a[i][step/2] = count++ ;
    34                }
    35   
    36                for (j = step/2; j >=0; --j)
    37                {
    38                    a[step/2][j] = count++ ;
    39                }
    40                tag = 1;
    41            }else{//逆時針
    42               
    43                for (i = 0; i < step/2; ++i)
    44                {
    45                    a[step/2][i] = count++;
    46                }
    47   
    48                for (j = step/2; j >=0; --j)
    49                {
    50                    a[j][step/2] = count++ ;
    51                }
    52                tag = 0;
    53            }
    54       }
    55   
    56       //print the matrix ;
    57        cout<<"n = "<<n<<endl;
    58        for (int i = 0; i < n; ++i)
    59        {
    60            for (int j = 0; j < n; ++j)
    61            {
    62                cout<<a[i][j]<<"/t";
    63            }
    64            cout<<endl;
    65        }
    66        return 0;
    67    }
    68   
    69    int main(int argc, char * argv[])
    70    {
    71        int n;
    72        cout<<"Please Input The N = ";
    73        cin>>n;
    74        matrix_print(n);
    75        return 0;
    76    }
-----------------------
算法思路:想法是想處理1,再按照2,3,4順時針方面輸出,然後按照5,6,7,8,9,
以此類推.(注意規律,每一次的數據個數分別爲:1,3,5,7,9...!)
-----------------------
     1    #include <cstdio>
     2    /*
     3    ***********************************************
     4    haiping@ubuntu:~/program/yv0928$ ./a.out
     5   
     6       The  Array matrix[8][8] is :
     7   
     8          1    28   27   26   25   24   23   22  
     9   
    10          2    29   48   47   46   45   44   21  
    11   
    12          3    30   49   60   59   58   43   20  
    13   
    14          4    31   50   61   64   57   42   19  
    15   
    16          5    32   51   62   63   56   41   18  
    17   
    18          6    33   52   53   54   55   40   17  
    19   
    20          7    34   35   36   37   38   39   16  
    21   
    22          8    9    10   11   12   13   14   15  
    23         
    24         
    25    **********************************************
    26    */
    27   
    28    void MatrixSpiralOutput(int n)
    29    {
    30        int **matrix = new int*[n]();
    31        for (int idx = 0; idx < n; idx++)
    32        {
    33            matrix[idx] = new int[n]();
    34        }
    35   
    36        int row = 0, col = 0;
    37        int i = 0;
    38        int len = n * n;
    39        int circle = 0;
    40   
    41        while (i < len)
    42        {
    43            for( ;row < n - circle; row++)
    44                matrix[row][col] = ++i;
    45   
    46            row--;
    47            col++;
    48   
    49            for( ; col < n - circle; col++)
    50                matrix[row][col] = ++i;
    51   
    52            row--;
    53            col--;
    54   
    55            for( ; row >= circle; row--)
    56                matrix[row][col] = ++i;
    57   
    58            row++;
    59            col--;
    60   
    61            for( ;col > circle; col--)
    62                matrix[row][col] = ++i;
    63   
    64            row++;
    65            col++;
    66   
    67            circle++;
    68        }
    69   
    70        printf("/n   The  Array matrix[%d][%d] is :", n, n);
    71        for(int k = 0; k < n; k++)
    72        {
    73            printf("/n/n      ");
    74            for(int j = 0; j < n; j++)
    75                printf("%-5d", matrix[k][j]);
    76        }
    77        printf("/n/n");
    78   
    79        for(int idx = 0 ; idx < n ; idx++)
    80            delete[] matrix[idx];
    81        delete [] matrix;
    82     
    83    }
    84   
    85    int main()
    86    {
    87     MatrixSpiralOutput(8);
    88     return 0;
    89    }
 ---------------
 算法思想:這裏主要是利用兩個變量跟蹤相應的下標變化,比較方便,原先我也想用上面的方面,發現比較麻煩
 如果想要得到由裏到外的螺旋,設定1)i= n*n,2)while(i>0),3)i--,這樣就可以了。我原來考慮從裏
 面往外打印,下標處理很麻煩,看來思維比較......!呵呵
 ---------------
     1    #include <iostream>
     2    #include <cstdio>
     3    #include <math.h>
     4   
     5    using namespace std;
     6    /*
     7    ****************************************************
     8    haiping@ubuntu:~/program/yv0928$ ./a.out
     9     n = 6
    10        1     3     4    10    11    21
    11        2     5     9    12    20    22
    12        6     8    13    19    23    30
    13        7    14    18    24    29    31
    14       15    17    25    28    32    35
    15       16    26    27    33    34    36
    16   
    17     ***************************************************
    18     */
    19   
    20    /*
    21    ***********************************
    22    //獲得n*n方陣中第i行第j列個元素
    23    int getElement1(int i ,int j,int n)
    24    {
    25        int num = i+j;
    26        int sum = num * (num+1) >>1;
    27     
    28        //過了對角線要另行處理
    29        //原作中這裏還是有bug,過了對角線,n=3,5,7等後面就不對了
    30        if(num > n-1) sum -= (num - n + 1) * (num - n + 1);
    31      
    32        //將判定條件改成 if(!(num&1)),改變方向
    33        if(!num & 1)     return sum + j+1;
    34        return sum + i+1;
    35    }
    36    ************************************
    37    */
    38    /*獲得n*n方陣中第i行第j列個元素*/
    39    int getElement1_m(int i ,int j,int n)
    40    {
    41        int num = i+j;
    42        int sum = num * (num+1) >>1;
    43        int s = n*n;
    44     
    45        //過了對角線要另行處理
    46        if(num > n-1)
    47            {
    48                int t = 2*(n-1)-(i+j)+1;
    49                    s -= t*(t+1)>>1;
    50            }
    51      
    52        //將判定條件改成 if(!(num&1)),改變方向
    53        if(num & 1)   return num > n-1?s +(n-i):sum + j+1;
    54        return num > n-1?s + (n-j):sum + i+1;
    55    }
    56    /*
    57    ****************************************************
    58    haiping@ubuntu:~/program/yv0928$ ./a.out
    59     n = 6
    60        1     2     3     4     5     6
    61       20    21    22    23    24     7
    62       19    32    33    34    25     8
    63       18    31    36    35    26     9
    64       17    30    29    28    27    10
    65       16    15    14    13    12    11
    66   
    67     ***************************************************
    68     */
    69   
    70    int getElement2(int i,int j,int n)
    71    {
    72        int k = min(min(i,j),n-1-max(i,j));
    73        int sum = 4 * ( k * (n + 1) - k * (k+1)); /*將判定條件改成 if(j <= i)改變方向*/ 
    74        if(j >= i)
    75            sum += (i+j) - 2*k + 1;
    76        else
    77            sum += ( n - 2*k - 1) * 4 - (i+j) + 2*k + 1;
    78        return sum;
    79    }
    80   
    81    /*
    82    ****************************************************
    83    haiping@ubuntu:~/program/yv0928$ ./a.out
    84     n = 5
    85        2     2     2     2     2
    86        2     1     1     1     2
    87        2     1     0     1     2
    88        2     1     1     1     2
    89        2     2     2     2     2
    90     
    91    ***************************************************
    92     */
    93   
    94    int getElement3(int i,int j,int n)
    95    {
    96        //n 爲任意正奇數
    97        int mid = n/2;
    98        return max(abs(i-mid) , abs(j-mid));
    99    }
   100   
   101    int main()
   102    {
   103        int n;
   104        int i,j;
   105        printf(" n = ");
   106        scanf("%d",&n);
   107               
   108        for(i = 0 ; i < n;i++){
   109            for(j = 0 ; j < n;j++)
   110                printf("%-5d ",getElement1_m(i,j,n));
   111            printf("/n");
   112        }
   113        return 0;
   114    }
   115   
 --------------------------------------
 算法思路:
 (思路來源http://hi.csdn.net/quietwave博主的回答)
 對於這類打印方陣的問題,可以用數學的方法,推導出
a[i][j] = F(i,j)中的F,即將第i行,第j列的元素用 i和j 的函數表示出來
然後再

    for(int i = 0 ; i < n;i++)
    {
        for(int j = 0 ; j < n;j++)
        printf("%5d ",getElement(i,j)); printf("/n");
    }

關鍵是完成函數
int getElement(int i,int j);

對於這道題,
可以看出每條副對角線上有 i+j 爲常量這個特點
所以可以想象第N條副對角線之前一定有
Sum = 1+2+...+N  = N*(N+1)/2 個數字
然後再考慮副對角線i+j的奇偶性,
是奇數則從i=0開始填數,所以a[i][j] = sum + i + 1;
是偶數則有 a[i][j] = sum + j + 1;

方陣改變方向後,則將上面判斷奇偶反過來,即可打印

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