C字矩阵
题目描述
有一个n*n的矩阵方格(1≤n≤30),小明想在方格中依次填入1~n*n,于是小明想到了一个C字方法。从方格的右上角填入1,然后以C的方式依次填入其他数字,如下图所示。
输入
第一行输入一个整数T(1≤T≤10),接下来T行,每行输入一个整数n(1≤n≤30)。
输出
将填满的方格中的数依次输出,每行输出n个数,每个数占4列,右对齐。
输入样例
2
3
6
输出样例
3 2 1
4 9 8
5 6 7
6 5 4 3 2 1
7 24 25 26 27 28
8 23 32 31 30 29
9 22 33 34 35 36
10 21 20 19 18 17
11 12 13 14 15 16
AC代码
#include<stdio.h>
void main()
{
int n[30][30] = { 0 };
int t, a, b, s, f;
//t:数据数 a、b:行、列 s:矩阵大小(s*s) f:下一个数的方向
scanf("%d", &t);
for (int i = 1; i <= t; i++)
{
scanf("%d", &s);
a = 0; b = s - 1; f = 1;
for (int j = 1; j <= s * s; j++)
{
n[a][b] = j; //将该数排入矩阵
switch (f) //判断下一个数的位置
{
case 1: //下一个数在左侧
{
b--;
if (b == 0 || n[a][b - 1] != 0) //遇到边界或左侧已经有数字
{
if (n[a + 1][b] == 0)f = 2; //判断需要往下还是往上
else f = 4;
}
break;
}
case 2: //下一个数在下方
{
a++;
if (b != 0 && n[a][b - 1] == 0)f = 1; //判断是否需要往左
else if (a == s - 1 || n[a + 1][b] != 0)f = 3; //判断是否需要往右
break;
}
case 3: //下一个数在右侧
{
b++;
if (b == s - 1 || n[a][b + 1] != 0) //遇到边界或右侧已经有数字
{
if (n[a - 1][b] == 0)f = 4; //判断需要网上还是往下
else f = 2;
}
break;
}
case 4: //下一个数在上方
{
a--;
if (n[a][b - 1] == 0)f = 1; //判断是否需要往左
else if (n[a - 1][b] != 0)f = 3; //判断是否需要往右
break;
}
}
}
for (int i = 0; i < s; i++) //输出排列好的矩阵
{
for (int j = 0; j < s; j++)
{
printf("%4d", n[i][j]);
n[i][j] = 0; //将已经输出的数组元素清零
}
printf("\n");
}
}
}
总结
- 理清逻辑关系,找到不同条件下需要做什么
例如:同样是先往左,“6”处接下来需要往下,“21”处接下来需要往上。
“16”处需要往上一行,而“21”处需要一直往上直到碰到有数的元素。
...... - 在判断下一个数的位置时也许可以用指针,效率更高。
- 用f来作方向指示变量不太易读,也许有更好的方法?
- 总体来说还算简单。