有这样一道题,即按照如下图形的规律打印出这个图形:
这个图形外面一圈“*”号很容易打印,它的核心是怎样打印里面的数字。
上面的数列可以把它看成一个二维数组,然后我们可以按照数组下标的变化分别给数组赋值。这时主要难点就是如何来确定下标的变化值。
我们可以先把它拆分成几种情况,来观察它们变化的规律。假设n为行列数,i为1到n之间的数。
当i=1时,数列为:
当i=2时,数列为:
当i=3时,数列为:
当i=4时,数列为:
当i=5时,数列为:
这们我们不难发现,元素第一次坐标的变化都是从上一次变化的最后的位置(如4,9,16,...)开始的,它的变化分为两种情况:(i=1不在此变化之列,应自行赋值)
当i为偶数时,数组坐标的变化是先下再左的方向变化,即先是x轴坐标不变,y轴坐标自增1,然后在转折点,y轴坐标不变,x轴坐标自减1。
当i为奇数时,数组坐标的变化是先上再右的方向变化,即先是x轴坐标不变,y轴坐标自减1,然后在转折点,y轴坐标不变,x轴坐标自增1。
另外,我们还可以发现,
当i=2时,纵向的值变化2次,横向的值变化1次
当i=3时,纵向的值变化3次,横向的值变化2次
当i=4时,纵向的值变化4次,横向的值变化3次
...............
这样,规律就出来了,我们可以确定每次i值变化时,循环给数组赋值的条件。具体参考代码如下:
static void Main(string[] args)
{
Console.WriteLine("请输入n的值:");
int n = Convert.ToInt32(Console.ReadLine()); //n代表要打印n行n列
int[,] Nums = new int[n, n]; //声明一个二维数组用来存储这些数字
int m;
m = (n - 1) / 2; //m为变化起始坐标
int x = m; int y = m; //数组下标,也是下面循环中数组随着i值变化的起点
int value = 1; //value为从1开始的整数,最大值为n²
Nums[x, y] = value++; //给数组中起始位置的元素赋值,赋值后让value自增1
for (int i = 2; i <= n; i++) //在循环里面给数组其它位置赋值
{
if (i % 2 == 0) //当i变为偶数时,数字是按先下再左的方向变化排列
{
x += 1; //当变化开始时,是要给该数右边的第一个元素赋值,所以先让x=x+1
for (int j = 0; j < i; j++) //然后x坐标不变,y轴的坐标依次变化自增
{ //y轴变化的次数等于当前i的值
Nums[x, y++] = value++;
}
y--; //当y轴变化完之后,y会自增1,(x,y)表示的元素实际在转折点下面的第一个位置,所以让y自减1,回到转折点的位置
for (int k = 0; k < i - 1; k++) //向左边赋值,y轴不变,x轴坐标依次变化自减
{ //x轴变化的次数为当前i-1的值
Nums[--x, y] = value++;
}
}
else //当i变为奇数时,数字是按先上再右的方向变化排列
{
x -= 1; //此时要给左边的第一个元素赋值,因此让x=x-1
for (int j = 0; j < i; j++) //然后x坐标不变,y轴的坐标依次变化自减
{
Nums[x, y--] = value++;
}
y++; //当y轴变化完之后,y会自减1,(x,y)表示的元素实际在转折点上面的第一个位置,所以让y自增1,回到转折点的位置
for (int k = 0; k < i - 1; k++) //向右边赋值,y轴不变,x轴坐标依次变化自增
{
Nums[++x, y] = value++;
}
}
}
//输出数组的值
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Console.Write(Nums[j, i] + "\t");
}
Console.WriteLine();
}
Console.ReadKey();
}
示例结果如下: