题目:
蛇形矩阵是由1开始的自然数依次排列成的一个矩阵上三角形。
输入n,代表n行n列的二维数组
输出要求:对于每一组数据,输出一个N行的蛇形矩阵。两组输出之间不要额外的空行。矩阵三角中同一行的数字用一个空格分开。行尾不要多余的空格。
样例输入:5
样例输出:
1 3 6 10 15
2 5 9 14
4 8 13
7 12
11
我的题解:
//#define _CRT_SECURE_NO_WARNINGS 1
//#include <stdio.h>
//#include <stdlib.h>
//int main()
//{
// int n;
// scanf("%d", &n);
// int a[n][n] = { 0 };
// int index = 1;
// a[0][0] = index;
// int i =1, j = 0,f=0;
// for (;f<n-1;f++) //-1是因为已经令i等于下一行的
// {
// int m=0,p=i;
// while (i >= 0 && a[i][j] == 0)
// {
// a[i--][j++]= ++index;
// }
// if (j - 1 >= n - 1) break;
// i = p+1;
// j= m; //重新让J变成0
// }
// for (i = 0; i < n; i++)
// {
// for (j = 0; j < n; j++)
// {
// printf("%4d", a[i][j]);
// }
// printf("\n");
// }
// return 0;
//}
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d", &n);
int a[100][100]; // 定义并初始化二维数组a
for (int z = 0; z < n; z++)
{
for (int x = 0; x < n; x++)
a[z][x] = 0;
}
int index = 1;
a[0][0] = index;
int i = 1, j = 0, f = 0;
for (; f < n - 1; f++) //-1是因为已经令i等于下一行的
{
int m = 0, p = i;
while (i >= 0 && a[i][j] == 0)
{
a[i--][j++] = ++index;
}
if (j - 1 >= n - 1) break;
i = p + 1;
j = m; //重新让J变成0
}
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (a[i][j] == 0) printf(" ");
else if (j != n - 1)printf("%d ", a[i][j]);
else if (j == n-1)printf("%d", a[i][j]);
}
printf("\n");
}
return 0;
}
第一段注释掉的代码是因为我发现利用定长数组无法通过编译,所以第二段代码人工初始化了整个二维数组。第二段代码p的用途是让i可以在自减到0时,来到蛇形矩阵的新一行数组(新的开始)
以下是我上网查询的另一种解法,更加巧妙,值得学习的点是它把每一行的(斜着看)起点和终点发现了是i,j互换。然后在输出时直接把j值的个数使用了n-1-i(i和j加起来等于n-1),巧妙地避开了每行的结尾多输出一个空格。
代码如下:
#include<stdio.h>
int main()
{
int n;
while(~scanf("%d", &n)){
int a[110][110]={0};//初始化
int i=1,tn=n,x=0,y=0;
// i代表 需要填的数值 tn循环的次数 x,y 起点坐标
while(tn--){
while(x>=0&&y<n)a[x--][y++]=i++;
// 边界跳出条件 循环填数 x-- y++ 就代表 按左下到右上的对角线移动填数
x++;//刚跳出边界的x肯定变成-1了 因此要回溯下回到终点 y不用回 因为本来就要y++
int tem=x;x=y;y=tem;// 将终点变为起点 交换坐标
}
for(x=0;x<n;x++){//打印 上三角 图形
for(y=0;y<n-x;y++)
printf("%d ",a[x][y]);
printf("\n");
}
}
return 0;
}