C语言程序设计100例之(28):直线蛇形阵
例28 直线蛇形阵
问题描述
编写程序,将自然数1、2、…、N2按蛇形方式逐个顺序存入N阶方阵。例如,当N=3和N=4时的直线蛇形阵如下图1所示。

图1 直线蛇形阵
输入格式
一个正整数n(1≤n≤20)。
输出格式
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 斜线蛇形阵
问题描述
编写程序,将自然数1、2、…、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=1、row=n-1、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、2、…、(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--)和向上填充(行号减1、列号不变,即row--)三个子过程不断交替完成的。
例如,图8所示的3阶螺旋下三角阵可以看成由向右填充(1、2、3),斜向下填充(4、5)和向上填充(6)这3个子过程完成的。4阶螺旋下三角阵可以看成由向右填充(1、2、3、4),斜向下填充(5、6、7)、向上填充(8、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;
}
C语言程序设计100例之(28):直线蛇形阵的更多相关文章
- 黑马程序员——经典C语言程序设计100例
1.数字排列 2.奖金分配问题 3.已知条件求解整数 4.输入日期判断第几天 5.输入整数进行排序 6.用*号显示字母C的图案 7.显示特殊图案 8.打印九九口诀 9.输出国际象棋棋盘 10.打印楼梯 ...
- C语言程序设计100例之(9):生理周期
例9 生理周期 问题描述 人生来就有三个生理周期,分别为体力.感情和智力周期,它们的周期长度为 23 天.28 天和33 天.每一个周期中有一天是高峰.在高峰这天,人会在相应的方面表现出色.例如 ...
- C语言程序设计100例之(22):插入排序
例22 插入排序 问题描述 排序是计算机程序设计中的一种重要操作,它的功能是将一个数据元素或记录的任意序列,重新排列成一个以关键字递增(或递减)排列的有序序列. 排序的方法有很多,简单插入排序就是一 ...
- C语言程序设计100例之(21):折半查找
例21 折半查找 问题描述 顺序查找是一种最简单和最基本的检索方法.其基本思想是:从检索表的一端(如表中第一个记录或最后一个记录)开始,逐个进行记录的关键字和给定值的比较.若某个记录的关键字和给定值 ...
- C语言程序设计100例之(15):除法算式
例15 除法算式 问题描述 输入正整数n(2≤n≤68),按从小到大输出所有形如abcde/fghi=n的表达式.其中a~i为1~9的一个排列. 输入格式 每行为一个正整数n (n <= 1 ...
- C语言程序设计100例之(12):Eratosthenes筛法求质数
例12 Eratosthenes筛法求质数 问题描述 Eratosthenes筛法的基本思想是:把某范围内的自然数从小到大依次排列好.宣布1不是质数,把它去掉:然后从余下的数中取出最小的数,宣布它 ...
- C语言程序设计100例之(4):水仙花数
例4 水仙花数 题目描述 一个三位整数(100-999),若各位数的立方和等于该数自身,则称其为“水仙花数”(如:153=13+53+33),找出所有的这种数. 输入格式 没有输入 输出格式 若 ...
- C语言程序设计100例之(6):数字反转
例6 数字反转 题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零(参见样例2). 输入格式 ...
- C语言程序设计100例之(14):丑数
例14 丑数 问题描述 丑数是其质因子只可能是2,3或5的数.前10个丑数分别为1, 2, 3, 4, 5, 6, 8, 9, 10, 12.输入一个正整数n,求第n个丑数. 输入格式 每行为一个 ...
随机推荐
- flex布局 居中
display:flex;justify-content: center;检查侧轴是否居中,比如古代竖着写字,检查字是否在每条竹简的中央. display:flex;align-items: cent ...
- JS 百度地图-右键菜单
JS 百度地图-右键菜单 /*-----------------标注右键删除-------------------------*/ var markerMenu = new BMap.ContextM ...
- 【Unity|C#】基础篇(20)——枚举器与迭代器(IEnumerable/IEnumerator)
[学习资料] <C#图解教程>(第18章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...
- 532-数组中的K-diff数对
532-数组中的K-diff数对 给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对.这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组 ...
- 疫情下的传统商企自救|4个Tips搭建销量过亿直播间
新冠肺炎爆发以来,线下商企遭受巨大冲击.出于疫情防控需要,不少门店选择暂时停业:而消费者们更是响应号召.足不出户.这场疫情促使消费者的消费习惯和方式进一步转向线上订购转变,直播.短视频等领域逆势而起, ...
- 如何在Windows上开启Ping或者禁止PING
方法1:命令行模式 进入服务器后 点击 开始——运行 输入命令: netsh firewall set icmpsetting 8 这样就可以在外部ping到服务器了 非常简单实用! 同样道理,如果想 ...
- 解决Office2016输入失效密钥之后无法输入的问题
第一步: 以管理员的身份运行cmd 第二步输入以下命令: cscript "C:\Program Files (x86)\Microsoft Office\Office16\OSPP.VBS ...
- 【做题笔记】洛谷P1506 拯救oibh总部
跑一遍染色法,最后判断哪些位置没被染色即可 一些技巧: 为了判断方便,把字符转换成 int 型的数字. 注意边界问题 详细解释见代码 #include <iostream> #includ ...
- (原创)SpringBoot入门
本文章是SpringBoot入门的介绍在这里 我会尽量写一些细节性的东西,我用的是IDEA2016 Tomcat7 JDK1.8 Maven3.3.9 IDEA Tomcat JDK Maven ...
- day01_2spring3
Bean基于XML和基于注解的装配 一.Bean基于XML的装配 1.生命周期接着day01_1来讲(了解) Bean生命周期的如图所示:用红色框起来的都是我们要研究的! 如图Bean is Read ...