回形取数浅谈----lanqiaoOJ 1517

题目

题目描述

回形取数就是沿矩阵的边取数,若当前方向上无数可取或所有数已经取过,则逆时针转九十度,从矩阵左上角开始,向下取数。

输入描述

输入两个不超过200的正整数m、n,表示矩阵的行与列。接下来输入m行n列整数,表示矩阵。

输出描述

输出只有一行,共m*n个数,为输入矩阵后回形取数得到的结果。数之间用空格分隔,行末不要有多余的空格。

输入样例                                                    

3 3                                                                               

1 2 3

4 5 6

7 8 9

输出样例

1 4 7 8 9 6 3 2 5

实例代码

dir = [(1, 0), (0, 1), (-1, 0), (0, -1)]   # 方向向量
m,n = map(int,input().split())  # 接受行数、列数
a = []    
for i in range(m):
    a.append(input().split())   # 接受每一行数据,m表示对应行序号
x,y = -1,0   
d = 0
sum = 0
while sum < m*n:
    sum = sum+1
    nx,ny = x+dir[d][0],y+dir[d][1]   # 改变坐标
    if nx < 0 or nx >= m or ny >= n or a[nx][ny] == -1:
        d = (d+1)%4
        x,y = x+dir[d][0],y+dir[d][1]
    else:
        x,y = nx,ny
    print(a[x][y],end=' ')  # 输出
    a[x][y] = -1  # 记忆已走过的路径

浅谈

这种题目有些类似于迷宫问题,但只需要按要求得出路径即可:

创建方向向量

在矩阵中有上、下、左、右四个方向,对应的方向向量组为

dir = [(1,0),(0,1),(-1,0),(0,-1)]

接收数据

        代码中的m,n = map(int,input().split())是接收第一行输入数据('3 3'),然后用split函数分割成['3','3'],最后转换为int整型,赋值给m、n,也就是m = 3,n = 3

        随后的for语句中,a.append(input().split())是从第2行数据开始(也就是'1 2 3',在for语句中指第i = 0行),接受每行数据,将每行数据分割之后生成的列表添加到a列表,直至for语句结束。此时a = [[1,2,3],[4,5,6],[7,8,9]]

改变坐标 

        代码中的nx,ny = x+dir[d][0],y+dir[d][1]将按照方向向量改变坐标赋值给nx、ny,当sum = 1,此时nx,ny = -1+dir[0][0],0+dir[0][1] = 0,0,由于if语句不通过,nx、ny的值就分别赋给x、y,坐标对应数字1。

        当sum=4时,nx,ny = 3,0,则符合if语句条件,将d=1,产生新的坐标,此时x,y = 2,1。所以当行列改变时,d的值也有所改变,其对应方向向量中所用的方向(比如当d=0时,代表坐标移动方向向下;d=1时,代表坐标移动方向向右……),这也就解释了d = (d+1)%4,因为有四个方向。

输出结果并记忆

最后输出每次循环的所走数字,a[x][y] = -1将走过的路径进行标记,所在坐标的值变为-1,避免重复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值