
前面的是故事背景,下面的才是题目的意思,所以题目的背景我就不截图了。
此题的意思就是以一个回形输出这个矩阵,但是这个矩阵是从一到n*m这个数字,题目的意思就是这样的。
所以话不多说,我们开始今天的分享
我们首先要有m,n这两个变量来表示矩阵的行和列,还要有一个数组来读入这个矩阵。
注意到n,m都大于一,小于一百。
为了防止边界性的问题,防止数组越界,有利于算法的实现,我们这里给数组多定义几个位置。
通常来说我们只需要多定义五个位置就可以了,这样能够提高代码的健壮性。
由于题目中并未提到要实现多组输入,所以我们无需实现该功能。
#include<stdio.h>
int main(){
int m,n;
int a[105][105];
scanf("%d %d",&m,&n);
、

我们想要实现如图的功能,这里我举例的是n,m均为4的情况,其他情况也能行。
如果我们直接去输出这样的图形,我们最开始从左到右输出直到输出完4这个数字,是不会产生问题的。
但是接下来就会出现问题了。我们在向下输出的时候该如何表示我们现在是从上往下输出的呢。
一般来说,我们设定,i 为行 j 为列
一般的我们会想到此时 j 是固定的,只需要变动 i 就好了。确实的,思路是这样没有错,但是我们想要表达我们从五这个数字开始,我们该怎么写呢。于是问题产生了。
如何解决这个问题呢。
其实只需要很简单的操作,设四个位置数,表示四个方向的位置(最上边的数字,最下边的数字,最左边的数字,最右边的数字),(但是我之前从未遇到过这样的输出,所以我没想到这样去做)
为了方便大家理解,我们设置这些未知数的名字 分别为 left right top bottom。
而由于我们是要从 1 开始输出的。所以我们这里定义一个num=1,每次把num放在矩阵上后,我们就让num++。同时num也能表示我们输出了多少个数字。所以我们在输出n*m这么多个数字之前,我们要一直进行从左到右,从上到下,从右到左,从下到上这四种循环。
这样是有利于大家理解的,提高了代码的可读性。
那么给出第一部分的代码
#include<stdio.h>
int main(){
int m,n;
int a[105][105];
scanf("%d %d",&m,&n);
int top=0,bottom=n-1;
int left=0,right=m-1;
int num=1;
接下来我们来实现功能。
从左到右 我们想到 此时 数组是在第一行,我们要使得 i 是一个定值,j来变动。则矩阵左侧是top,让 num 来填充这个位置,每填充完一次后就要++,我们完成这一段之后,等到再次到从左到右输出的时候,就已经是第二行了,并且在我们在下一步从上到下的输出过程中,我们要从第二个数字开始,如上图我们输出完第一行以后,我们从上到下输出要从5开始输出,所以这样做又有助于下一步的进行。
关于循环终止的条件,我们在输出的过程中,要时刻注意num是否小于等于n*m,因为我们一共就要输出这么多个数字,如果没有这个条件,我们很可能在某一次输出时多输出几个数字。
所以我们每完成一次之后要 top++。
for(int j=left;j<=right && num<=n*m ;j++){
a[top][j]=num++;
}
top++;
从上到下,我们输出的是最右行的数字,所以我们矩阵右侧的数字固定为 right,左侧来进行变动,这样使得矩阵来从上到下输出,因为 i 决定了行数。与 top 同样的道理,但是略有区别,我们在从上到下输出的过程中,我们占据的是最右侧的位置,所以每次进行到这里的时候,我们的右侧都要少一个,所以 right —
for(int i=top;i<=bottom && num<=n*m ;i++){
a[i][right]=num++;
}
right–;
下面的两个过程也是同理的,但是从右到左,从下到上。我们循环的第三个位置是–,而不是++。
接下来给出功能实现的代码
while(num<=n*m){
for(int j=left;j<=right && num<=n*m ;j++){
a[top][j]=num++;
}
top++;
for(int i=top;i<=bottom && num<=n*m ;i++){
a[i][right]=num++;
}
right–;
for(int j=right;j>=left && num<=n*m;j–) {
a[bottom][j]=num++;
}
bottom–;
for(int i=bottom;i>=top && num<=n*m ;i–){
a[i][left]=num++;
}
left++;
}
我们这样实现功能以后,我们只需要正常输出就好了。只要不是最后每行的最后一个数字,后面都要有一个空格,每进行完一行数字的输出以后,我们就要输出一个空格。
所以代码如下
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
printf("%d",a[i][j]);
if(j!=m-1) printf(" ");
}
printf("\\n");
}
于是这道题就结束了。
感谢您的阅读,如果您觉得我的思路还可以的话,不妨给我留一个点赞吧。
那么接下来我给出我的完成c语言代码。
#include<stdio.h>
int main(){
int m,n;
int a[105][105];
scanf("%d %d",&m,&n);
int top=0,bottom=n-1;
int left=0,right=m-1;
int num=1;
while(num<=n*m){
for(int j=left;j<=right && num<=n*m ;j++){
a[top][j]=num++;
}
top++;
for(int i=top;i<=bottom && num<=n*m ;i++){
a[i][right]=num++;
}
right–;
for(int j=right;j>=left && num<=n*m;j–) {
a[bottom][j]=num++;
}
bottom–;
for(int i=bottom;i>=top && num<=n*m ;i–){
a[i][left]=num++;
}
left++;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
printf("%d",a[i][j]);
if(j!=m-1) printf(" ");
}
printf("\\n");
}
return 0;
}



![[C++]算法双指针 复写0-171主机测评](https://www.171host.com/wp-content/uploads/2026/09/20260910013601-6aa2098179e1b-220x150.png)