关于打印一个有趣的数字图形的问题

有这样一道题,即按照如下图形的规律打印出这个图形:


这个图形外面一圈“*”号很容易打印,它的核心是怎样打印里面的数字。

上面的数列可以把它看成一个二维数组,然后我们可以按照数组下标的变化分别给数组赋值。这时主要难点就是如何来确定下标的变化值。

我们可以先把它拆分成几种情况,来观察它们变化的规律。假设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();
        }
示例结果如下:





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值