回旋矩形C语言,C语言程序设计100例之(27):回旋方阵
例27 ?????? 回旋方陣
問題描述
編寫程序,生成從內到外是連續的自然數排列的回旋方陣。例如,當n=3和n=4時的回旋方陣如下圖1所示。
圖1? 由內到外回旋方陣
輸入格式
一個正整數n(1≤n≤20)。
輸出格式
N階滿足要求的由內到外回旋方陣。輸出時共n行,每行n個數,每個數占4列。
輸入樣例
5
輸出樣例
21? 20? 19? 18? 17
22?? 7?? 6?? 5? 16
23?? 8?? 1?? 4? 15
24?? 9?? 2?? 3? 14
25? 10? 11? 12? 13
(1)編程思路1。
觀察圖1及樣例,由內到外回旋方陣的構造方法是:先將1填入方陣的中心位置(即i=(n-1)/2;? j=(n-1)/2;? a[i][j]=1),然后其余數的填寫可以看成由向下填充(列號不變、行號加1,即i++)、向右填充(行號不變、列號加1,即j++)、向上填充(行號減1、列號不變,即i--)和向左填充(行號不變、列號減1,即j--)四個子過程不斷交替完成的。
例如,圖1所示的4階由內到外回旋方陣可以看成由向下填充(2)、向右填充(3)、向上填充(4、5)、向左填充(6、7)、向下填充(8、9、10)、向右填充(11、12、13)、向上填充(14、15、16)這7個子過程完成的。
n階由內到外回旋方陣可以看成由4個子過程交替進行來完成的,這4個子過程依次為向下填充、向右填充、向上填充、向左填充,用變量d來表示,其取值為1、2、3或4,1表示向下填充,2表示向右填充,3表示向上填充,4表示向左填充。每個子過程結束后,切換填充方向,方式為:d++,若d>4,d=1。
在這一序列子過程中,第1、2子過程填寫1個數,第3、4子過程填寫2個數,第5、6子過程填寫3個數,第7、8子過程填寫4個數,…,直到最后一個數n2填寫完畢。
(2)源程序1。
#include
int main()
{
int a[20][20]={0},i,j,k=1,n,x,d,cnt;
scanf("%d",&n);
i=(n-1)/2;? j=(n-1)/2;
a[i][j]=k++;
d=1;cnt=1;x=0;
while (k<=n*n)
{
switch (d)
{
case 1:i++;
a[i][j]=k++;
x++;
if (x==cnt)
d=2,x=0;
break;
case 2:j++;
a[i][j]=k++;
x++;
if (x==cnt)
d=3,x=0,cnt++;
break;
case 3:i--;
a[i][j]=k++;
x++;
if (x==cnt)
d=4,x=0;
break;
case 4:j--;
a[i][j]=k++;
x++;
if (x==cnt)
d=1,x=0,cnt++;
break;
}
}
for (i=0;i
{
for (j=0;j
printf("%4d",a[i][j]);
printf("
");
}
return 0;
}
(3)編程思路2。
觀察1所示的由內到外回旋方陣,可以看出,n階由內到外回旋方陣可以看成是自然數n*n~1由外向內遞減填充數字而構造成。
構造時,奇數階方陣從左下角開始(即row=n-1、col=0),循環經過向上填充、向右填充、向下填充和向左填充的過程,直到全部數字填充完畢;偶數階方陣從右上角開始(即row=0、col=n-1),循環經過向下填充、向左填充、向上填充和向右填充的過程,直到全部數字填充完畢。由于奇數階和偶數階填充順序有差異,定義一個變量s作為標志,s==1時,表示進行向下填充和向左填充;s==-1表示進行向上填充和向右填充。奇數階構造時,s初值為-1;偶數階時為1。
為了清楚地標記出每次填充結束的位置,定義x1、x2、y1和y2這四個變量來分別保存向上、向下、向左和向右填充的邊界。初始時, x1=0、y1=0、x2=n、y2=n。
例如,向上填充時,循環過程為
while(row>=x1)??????????? //? 向上填充
{
a[row][col]=num;
row--;???????????? // 行號減1、列號不變,向上填充
num--;
}
一次向上填充結束后,x1加1(即x1++),這樣向上填充的上邊界增大了,下次就會少填一行。 同時修改row和col,即row--、col--,從而得到向左填充的起點。
由于奇數階方陣先向上填充,這樣當向左填充時,最底行的左下角已經填有數字,因此,向左填充的邊界的初始值應為1(即y1=1)。同理,偶數階方陣的初始向右填充的邊界y2=n-1。
(4)源程序2。
#include
int main()
{
int row,col,a[20][20]={0},n,num;
int x1,x2,y1,y2,s;
//? x1:填充上邊界?? x2:填充下邊界
//? y1:填充左邊界?? y2:填充右邊界
//? s:數組元素升降標記,s等于l為升,s等于-1為降
scanf("%d",&n);
num=n*n;
x1=0;? y1=0; x2=n; y2=n;
if (n%2==0)?? { row=0;col=n-1;? y2=n-1; s=1;}
else????? { row=n-1; col=0;? y1=1; s=-1;}
while (num>=1)
{
if(s==1)
{
while (row
{? a[row][col]=num--;row++;? }
row--;? col--;???? ??// 得到向左填充的起點
x2--;????????????? // 向下填充的下邊界縮小
while (col>=y1)???? // 向左填充
{ a[row][col]=num--;col--; }
col++;???? row--;?? // 得到向上填充的起點
y1++;????????????? // 向左填充的左邊界增大
s=-1;??????? ??????// 切換升降標志
}
else
{
while(row>=x1)??? //? 向上填充
{ a[row][col]=num--;? row--; }
row++;??? col++;? //? 得到向右填充的起點
x1++;???????????? //? 向上填充的上邊界增大
while (col
{a[row][col]=num--;col++;}
col--;??? row++;??? // 得到向下填充的起點
y2--;????????????? //? 向右填充的右邊界縮小
s=1;????????????? //? 切換升降標志
}
}
for (int i=0;i
{
for (int j=0;j
printf("%4d",a[i][j]);
printf("
");
}
return 0;
}
習題27
27-1? 由外向內回旋方陣
問題描述
編寫程序,生成從外到內是連續的自然數排列的回旋方陣。例如,當n=3和n=4時的回旋方陣如下圖2所示。
圖2? 由外向內回旋方陣
輸入格式
一個正整數n(1≤n≤20)。
輸出格式
N階滿足要求的由外向內回旋方陣。輸出時共n行,每行n個數,每個數占4列。
輸入樣例
5
輸出樣例
1? 16? 15? 14? 13
2? 17? 24? 23? 12
3? 18? 25? 22? 11
4? 19? 20? 21? 10
5?? 6?? 7?? 8?? 9
(1)編程思路。
由外向內回旋方陣可以通過對方陣的每一圈的各邊的各個元素順序賦值來完成。每一圈的賦值又依次包含4個順序的過程。
1)一圈的左列從上至下遞增賦值,一直賦值到超過最底行(即row==n)或下一位置已經賦值了(即a[row+1][col]!=0)。
while(row+1
a[++row][col]=++num;????? // 列號col不變,行號row遞增,數num遞增
2)一圈的下行從左至右遞增賦值,一直賦值到超過最右列(即col==n)或下一位置已經賦值了(即a[row][col+1]!=0)。
while(col+1
a[row][++col]=++num;???? // 行號row不變,列號col遞增,數num遞增
3)一圈的右列從下至上遞增賦值,一直賦值到超過最頂列(即row==-1)或下一位置已經賦值了(即a[row-1][col]!=0)。
while(row-1>=0&&!a[row-1][col])
a[--row][col]=++num;???? // 行號row遞減,列號col不變,數num遞增
4)一圈的上行從右至左遞增賦值,一直賦值到超過最左列(即col==-1)或下一位置已經賦值了(即a[row][col-1]!=0)。
while(col-1>=0&&!a[row][col-1])
a[row][--col]=++num;???? // 行號row不變,列號col遞減,數num遞增
初始時,row=0、col=0、num=1。
(2)源程序。
#include
int main()
{
int a[20][20]={0};
int n,row,col,num=0;
scanf("%d",&n);
num=a[row=0][col=0]=1;?????????????? // 第0行第0列輸入起始1
while(num
{
while(row+1
a[++row][col]=++num;
while(col+1
a[row][++col]=++num;
while(row-1>=0&&!a[row-1][col])?? // 向上填充
a[--row][col]=++num;
while(col-1>=0&&!a[row][col-1])??? // 向左填充
a[row][--col]=++num;
}
for (int i=0;i
{
for (int j=0;j
printf("%4d",a[i][j]);
printf("
");
}
return 0;
}
27-2? 間斷折疊方陣
問題描述
n階間斷折疊方陣是把從起始數1開始的n2個整數折疊為n行n列的n階方陣:起始數1置于方陣的左上角,然后從起始數開始遞增,每一層從第1行開始,先豎向下再折轉向左,層層折疊地排列為間斷折疊方陣。
例如,當n=4和n=5時的間斷折疊方陣如下圖3所示。
圖3? 間斷折疊方陣
輸入格式
一個正整數n(1≤n≤20)。
輸出格式
N階滿足要求的間斷折疊方陣。輸出時共n行,每行n個數,每個數占4列。
輸入樣例
5
輸出樣例
1?? 2?? 5? 10? 17
4?? 3?? 6? 11? 18
9?? 8?? 7? 12? 19
16? 15? 14? 13? 20
25? 24? 23? 22? 21
(1)編程思路。
定義一個二維數組a保存方陣的各元素,從給定的起始數1開始,按遞增1取值,根據間斷折疊方陣的構造特點給二維數組a[n][n]賦值。
起始數1賦值給a[0][0]。
除a[0][0]外,n階方陣還有疊折的n-1層:
第i層(i=1、2、…、n-1)的起始位置為(0,i),隨后列號col不變行號row遞增(即向下填寫),至row=i時折轉;轉折后,行號row不變列號col遞減(即向左填寫),至col=0時該層結束,在每一位置分別按遞增值賦值給a[row][col]。
具體過程描述為:
a[0][0]=1;
num=2;
for(i=1;i
{
row=0;? col=i;?????????????????????????? // 確定每層起始位置
a[row][col]= num++;
while(row
while(col>0)? a[row][--col]=num++;??? // 再向左填
}
(2)源程序。
#include
int main()
{
int i,m,num,row,col,a[20][20];
scanf("%d",&m);
a[0][0]=1;
num=2;
for (i=1;i
{
row=0;? col=i;
a[row][col]=num++;
while(row
while(col>0)? a[row][--col]=num++;
}
for (i=0;i
{
for (int j=0;j
printf("%4d",a[i][j]);
printf("
");
}
return 0;
}
27-3 回轉折疊方陣
問題描述
n階回轉折疊方陣是把起始數1置于方陣的左上角,然后從起始數開始遞增,偶數層從第1行開始,先豎向下再折轉向左;奇數層從第1列開始,先橫向右再豎向上,呈首尾連接,層層折疊地排列為回轉折疊方陣。例如,當n=4和n=5時的回轉折疊方陣如下圖4所示。
圖4? 回轉折疊方陣
輸入格式
一個正整數n(1≤n≤20)。
輸出格式
N階滿足要求的回轉折疊方陣。輸出時共n行,每行n個數,每個數占4列。
輸入樣例
5
輸出樣例
1?? 2?? 9? 10? 25
4?? 3?? 8? 11? 24
5?? 6?? 7? 12? 23
16? 15? 14? 13? 22
17? 18? 19? 20? 21
(1)編程思路。
回轉折疊方陣構造過程的奇數層(注意:由于數組下標從0開始,因此程序中層號也從0開始)與間斷折疊構造過程相同,偶數層構造方法改變為:該層的起始位置為(i,0),隨后行號row不變列號col遞增(即向右填寫),至col=i時折轉;轉折后,列號col不變行號row遞減(即向上填寫),至row=0時該層結束,在每一位置分別按遞增值賦值給a[row][col]。具體描述為:
if (i%2==0)
{
row=i;col=0;???????????????????? // 確定偶數層的起始位置
a[row][col]=num++;
while(col
while(row>0) a[--row][col]=num++;? // 再向上填
}
(2)源程序。
#include
int main()
{
int i,m,num,row,col,a[20][20];
scanf("%d",&m);
a[0][0]=1;
num=2;
for(i=1;i
{
if (i%2==1)
{
row=0;? col=i;
a[row][col]=num++;
while(row
while(col>0)? a[row][--col]=num++;
}
else
{
row=i;col=0;
a[row][col]=num++;
while(col
while(row>0) a[--row][col]=num++;
}
}
for (i=0;i
{
for (int j=0;j
printf("%4d",a[i][j]);
printf("
");
}
return 0;
}
總結
以上是生活随笔為你收集整理的回旋矩形C语言,C语言程序设计100例之(27):回旋方阵的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c 语言 string类型转换,用标准c
- 下一篇: c语言学生信息管理系统框架,vue实现学