問題描述編程
編寫程序,將天然數一、二、…、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能夠看出,直線蛇形陣的構造是從最底行(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。
#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;
}
問題描述
編寫程序,將天然數一、二、…、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
問題描述
圖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;
}
問題描述
編寫程序,將天然數一、二、…、(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;
}