需求:N*N矩阵,构造如下图所示下三角蛇形矩阵
需求分析:
首先矩阵要填入的数值范围,假设矩阵为N*N,那么需要填入的数是1到(N*N+N)/2
下三角矩阵有三个规律,一是沿着主对角线方向向下移动,下标i,j每次分别加1;二是水平向左移动,下标j每次减1,i保持不变;三是垂直向上移动,下标i每次减1,j保持不变
重点是方向在一定条件下发生改变,如果当前沿着主对角线向下移动,那么要检测i和j是否移动边界(撞墙),或者按规律下一个i+1,j+1的格子是否已经有数据(和撞墙是一个逻辑),如果这两个条件有一个成立,那么方向就需要改变为水平向左移动。同样,当前是向左或向上移动时,一样的规律即可完成矩阵
#include <stdio.h>
#include <stdlib.h>
#define N 100 //矩阵大小
int a[N][N] = {0}; //矩阵,默认值为0
int n = 0; //矩阵实际大小
typedef enum _MOVETYPE //移动方向类型
{
move_top = 1, //向上移动 ,i--,j不变
move_left = 2, //向左移动,i不变,j--
move_line = 3 //主对角线移动,i++,j++
}MOVETYPE;
void fun()
{
int i=0,j=0;
MOVETYPE mt = move_line; //初始移动方向为主对角线方向
for(int k=1;k<=(n*n+n)/2;k++)
{
if(a[i][j] == 0) //如果当前格可填,则填入数值
{
a[i][j] = k;
}
else //否则循环变量减1,表示当前无法填入,继续查找下一个合适位置
k--;
//根据当前移动方向进行下一个格子的判定
switch(mt)
{
case move_top:
{
//如果下一格出界或者已经有数据,表示撞墙,移动方向右拐
if(i==0 || a[i-1][j] != 0)
{
mt = move_line;
i++;
j++;
}
else
i--;
}break;
case move_left:
{
if(j==0 || a[i][j-1] != 0)
{
mt = move_top;
i--;
}
else
j--;
}break;
case move_line:
{
if(i==n-1 || j==n-1 || a[i+1][j+1] != 0)
{
mt = move_left;
j--;
}
else
{
i++;
j++;
}
}break;
}
}
}
int main()
{
while(1)
{
system("cls");
printf("请输入矩阵大小(100以内),输入小于等于1则退出:");
scanf("%d",&n);
if(n<=1)
return 0;
int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i][j] = 0;
fun();
//
for(i=0;i<n;i++)
{
for(j=0;j<=i;j++)
{
printf("%4d",a[i][j]);
}
printf("\n");
}
printf("\n");
system("pause");
}
return 0;
}