打印螺旋队列(更简单的方法)(难度:1颗星)

输入n*n矩阵的n值,打印出一个螺旋矩阵,如下面例子:

当n= 5时,输出

    1    2    3    4    5
   16   17   18   19    6
   15   24   25   20    7
   14   23   22   21    8
   13   12   11   10    9

更简单的方法1:

根据x,y的坐标值,然后通过计算,直接打印对应的值,以中心点建立直角坐标系,这样外面的数字就可以一圈一圈的展开。

参考代码:

#include <stdio.h>

#define MAXI(a, b) ((a) > (b) ? (a) : (b))
#define ABSI(a) ((a) > 0 ? (a) : (-a))

int main()
{
    int n, saveSquareN, i, j, maxTwo, nEdge, square;
    scanf_s("%d", &n);
    saveSquareN = n * n;
    n /= 2;

    for (i = -n; i <= n; i++)
    {
        for (j = -n; j <= n; j++)
        {
            if (0 == saveSquareN % 2 && (0 == i || 0 == j))
                continue;

            maxTwo = MAXI(ABSI(i), ABSI(j));
            nEdge = saveSquareN % 2 ? 2 * maxTwo + 1 : 2 * maxTwo;
            square = nEdge * nEdge;
            if (i == maxTwo)
                square % 2 ? printf("%5d", saveSquareN + 1 - ((2 * square - 5 * (nEdge - 1)) / 2 + j)) : printf("%5d", saveSquareN + 1 - (int)((2 * square - 5 * (nEdge - 1)) / 2.0 + (j > 0 ? j - 0.5 : j + 0.5)));
            else if (i == -maxTwo)
                square % 2 ? printf("%5d", saveSquareN + 1 - ((2 * square - (nEdge - 1)) / 2 - j)) : printf("%5d", saveSquareN + 1 - (int)((2 * square - (nEdge - 1)) / 2.0 - (j > 0 ? j - 0.5 : j + 0.5)));
            else if (j == maxTwo)
                square % 2 ? printf("%5d", saveSquareN + 1 - ((2 * square - 3 * (nEdge - 1)) / 2 - i)) : printf("%5d", saveSquareN + 1 - (int)((2 * square - 3 * (nEdge - 1)) / 2.0 - (i > 0 ? i - 0.5 : i + 0.5)));
            else
                square % 2 ? printf("%5d", saveSquareN + 1 - ((2 * square - 7 * (nEdge - 1)) / 2 + i)) : printf("%5d", saveSquareN + 1 - (int)((2 * square - 7 * (nEdge - 1)) / 2.0 + (i > 0 ? i - 0.5 : i + 0.5)));
        }
        if (saveSquareN % 2 || i) 
            printf("\n");
    }
    return 0;
}

更简单的方法2:

通过数组保存4个方向的增量,然后一直沿着某个方向走,只要合法,继续走,不合法则换一个方向继续走,直到全部走完为止。

参考代码:

#include <stdio.h>

int arr[100][100], n;
int dir[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
int IsPosOk(int x, int y)
{
    return x >= 0 && x < n && y >= 0 && y < n && 0 == arr[x][y];
}

int main()
{
    int i, j, PosX  = 0, PosY = 0, nCount = 1, curDir = 0;
    scanf_s("%d", &n);
    arr[0][0] = nCount++;
    while (nCount <= n * n)
    {
        if (IsPosOk(PosX + dir[curDir][0], PosY + dir[curDir][1]))
        {
            PosX += dir[curDir][0];
            PosY += dir[curDir][1];
            arr[PosX][PosY] = nCount++;
        }
        else
            curDir = (curDir + 1) % 4;
    }

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
            printf("%5d", arr[i][j]);
        printf("\n");
    }
    return 0;
}

运行结果:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值