【算法题】螺旋矩阵III (求解n阶蛇形矩阵)

一、问题的提出

n阶蛇形矩阵的特点是按照图1所示的方式排列元素。n阶蛇形矩阵是指矩阵的大小为n×n,其中n为正整数。

题目背景

一个 n  n 列的螺旋矩阵可由如图1所示的方法生成,观察图片,找出填数规律。填数规则为从 1 开始填到 n×n

图1  n  n 列的螺旋矩阵(蛇形矩阵)

 现在给出矩阵大小 n 以及 i  j,请你求出该矩阵中第 i 行第 j 列的数是多少。

题目描述

输入格式

从标准输入读入数据。 共一行,包含三个整数 n1n1,000)、i1in)、j1jn),每两个整数之间用一个空格隔开,分别表示矩阵大小、待求的数所在的行号和列号。

输出格式

输出到标准输出。 一个整数,表示相应矩阵中第 i 行第 j 列的数。

输入输出样例

输入 #1复制

8 2 8

输出 #1复制

43

说明/提示

子任务

  • 对于 30% 的测试数据,n10
  • 对于 60% 的测试数据,n100
  • 对于 100% 的测试数据,n1,000
  • 特别地,对于 20% 的测试数据,i=j=1

提示

根据本题的填数规则,一个 8×8 的螺旋矩阵应该长这样(如图2所示):

图2 88列的螺旋矩阵(蛇形矩阵)

 二、解题的思路

由图3可知,这是个旋转45º的Z形矩阵,当然折返长度是不相等的。仔细看图1发现:当向右上方填数时,如行号为0则向右(行号不变,列号加1),如是列号到n时则向下(列号减1,行号加1),然后向左下方填数,此时,如列号为0则向下,如是行号到n时则向右(行号减1,列号加1),然后向右一方填数,如此重复直到最后行、最后列填完为止。

图3 蛇形矩阵分析图

三、矩阵生成算法

nn列,第一行为0行,第一列为0列。从(0,0)1开始,方向设为从左下往右上。

当从左下往右上时,如行号已为0则列号加1方向向反(从右上往左下),否则行号减1,列号加1,如列号达n则列号为n-1,行号加1方向向反(从右上往左下)

当从右上往左下时,如列号已为0则行号加1方向向反(从左下往右上),否则行号加1,列号减1,如行号达n则列号加1,行号为n-1方向向反(从左下往右上)

当行号和列号都为n-1时结束。

程序代码如下:

def prt(hm):                 # 打印二维列表
    for i in range(N):
        for j in range(N):
            print("%3d" % hm[i][j], end='')
        print()
 
def Helix_MatrixII(n):
    cnt = 1
    i = j = 0
    k = 1
    while True:
        matrix[i][j] = cnt
        if i == n-1 and j == n-1:
            break
        if k == 1:           # 从左下往右上 
            if i == 0 :
                j += 1
                if j >= n:
                    j = n-1
                    i = i+1 if i < n -1 else n-1
                k = -1
            elif j == n-1:
                i += 1
                k = -1
            else:
                i -= 1
                j += 1
        else:                # 从右上往左下
            if j == 0 :
                i += 1
                if i >= n:
                    i = n-1
                    j = j+1 if j < n -1 else n-1
                k = 1
            elif i == n-1:
                j += 1
                k = 1
            else:
                i += 1
                j -= 1
        cnt += 1
            
N = 7
matrix = []             # 初始化二维矩阵matrix(二维列表)
for i in range(N):
    matrix.append([])
    for j in range(N):
        matrix[i].append(0)
Helix_MatrixII(N)
prt(matrix)

执行结果:

 四、题目求解算法

题目要求输入矩阵规模n和坐标(i, j)三个参数,求出矩阵(i, j)处的元素值。所以先按n求出矩阵,现按坐标输出元素值。

程序代码如下:

def Helix_MatrixII(n):
    cnt = 1
    i = j = 0
    k = 1
    while True:
        matrix[i][j] = cnt
        if i == n-1 and j == n-1:
            break
        if k == 1:        # 从左下往右上
            if i == 0 :
                j += 1
                if j >= n:
                    j = n-1
                    i = i+1 if i < n -1 else n-1
                k = -1
            elif j == n-1:
                i += 1
                k = -1
            else:
                i -= 1
                j += 1
        else:             # 从右上往左下
            if j == 0 :
                i += 1
                if i >= n:
                    i = n-1
                    j = j+1 if j < n -1 else n-1
                k = 1
            elif i == n-1:
                j += 1
                k = 1
            else:
                i += 1
                j -= 1
        cnt += 1
          
N, x, y = map(int, input().split())
matrix = []               # 初始化二维矩阵matrix(二维列表)
for i in range(N):
    matrix.append([])
    for j in range(N):
        matrix[i].append(0)
Helix_MatrixII(N)
print(matrix[x-1][y-1])

执行结果:

 

猜你喜欢

转载自blog.csdn.net/hz_zhangrl/article/details/132262026