方阵的主对角线之上称为“上三角”。
请你设计一个用于填充n阶方阵的上三角区域的程序。填充的规则是:使用1,2,3….的自然数列,从左上角开始,按照顺时针方向螺旋填充。
例如:当n=3时,输出:
1 2 3
6 4
5
当n=4时,输出:
1 2 3 4
9 10 5
8 6
7
当n=5时,输出:
1 2 3 4 5
12 13 14 6
11 15 7
10 8
9
程序运行时,要求用户输入整数n(3~20)
程序输出:方阵的上三角部分。
要求格式:每个数据宽度为4,右对齐。
分析:
思路1:先将输出存入二维数组,一个变量控制数据写入数组的方向,计算完所有输出后一起输出。[实现简单,但浪费空间严重]
思路2:顺序输出每个数字,计算并控制数字的显示位置,使数字直接输出到正确有位置。[时间换空间]
思路3:逐行从左到右计算并输出每个数字。[时间换空间]
解:
采用思路3的程序:
#include <stdio.h>
#define min(a, b) (((a) < (b)) ? (a) : (b))
typedef int INT32;
typedef char INT8;
typedef void VOID;
//逐行计算并输出每个值
VOID f(INT32 n)
{
INT32 row, vol; //总行,列计数
INT32 curRow, curVol; //当前位置行列值
INT32 cir; //圈数,每个直角三角形为1圈
INT32 x,y; //每圈数字左上角的坐标
INT32 startNum; //当前圈起始值
INT32 curN; //当前圈总行(列)数
INT32 num; //当前值
INT32 i;
row = n;
vol = n;
for(curRow=1; curRow<=row; curRow++)
{
for(curVol=1; curVol<=vol; curVol++)
{
cir = min(min(curRow,curVol), min(curVol, vol-curVol+1)); //计算当前位置为第几圈
//计算当前圈左上角数字
startNum = 1;
for(i=1; i<cir; i++)
startNum += 3*(n-1-3*(i-1));
curN = n-3*(cir-1); //当前圈总行/列数
x = y = cir; //当前圈左上角座标(1起始)
//计算当前值
if(curRow == x )
num = startNum + curVol - x; //处于直角三角形上直角边
else if(curVol == y)
num = startNum + 3*(n-1-3*(i-1)) - (curRow-y); //处于直角三角形左直角边
else
num = startNum + curN - 1 + curRow - cir; //处于直角三角形斜边
printf("%4d", num);
}
printf("\n");
vol--;
}
}
INT32 main(INT32 argc, INT32 *argv[])
{
INT32 n;
printf("请输入整数>3...\n");
scanf("%d", &n);
f(n);
return 0;
}