matlab顺时针螺旋递增矩阵,Spiral Memory(顺时针有序螺旋矩阵)

问题描述:

You come across an experimental new kind of memory stored on an infinite two-dimensional grid.

Each square on the grid is allocated in a spiral pattern starting at a location marked 1 and then

counting up while spiraling outward. For example, the first few squares are allocated like this:

17 16 15 14 13

18 5 4 3 12

19 6 1 2 11

20 7 8 9 10

21 22 23---> ...

While this is very space-efficient (no squares are skipped), requested data must be carried back to

square 1 (the location of the only access port for this memory system) by programs that can only

move up, down, left, or right. They always take the shortest path: the Manhattan Distance between

the location of the data and square 1.

For example:

Data from square 1 is carried 0 steps, since it's at the access port.

Data from square 12 is carried 3 steps, such as: down, left, left.

Data from square 23 is carried only 2 steps: up twice.

Data from square 1024 must be carried 31 steps.

How many steps are required to carry the data from the square identified in your puzzle input all

the way to the access port?

解决代码(通过归纳法)

'''

螺旋数组用每个节点的坐标位置保存在节点属性position中

值为1的节点定义位置为(0,0),其余节点坐标都为与(0,0)节点的相对位置

按照打印的话,看起来就像是这样:

17 16 15 14 13

18 5 4 3 12

19 6 1 2 11

20 7 8 9 10

21 22 23--->...

由内往外逆时针生序排列

归纳规律

初始点--------------第1个节点

1:1_(0,0)

第1次 多向移动--------------右上 两个方向上各移动1次 向右移动相当于+(1,0) 向上移动相当于+(0,1)

2(自上个节点:向右1位): 1_(0,0) 2_(1,0)

3(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1)

第2次,多向移动-------------左下 两个方向上各移动各2次 向左移动相当于+(-1,0) 向下移动相当于+(0,-1)

4(自上个节点:向左1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1)

5(自上个节点:向左1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1)

6(自上个节点:向下1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0)

7(自上个节点:向下1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1)

第3次,多向移动-------------右上 两个方向上各移动3位 向右移动相当于+(1,0) 向上移动相当于+(0,1)

8 (自上个节点:向右1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1)

9 (自上个节点:向右1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1)

10(自上个节点:向右1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1)

11(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0)

12(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1)

13(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2)

第4次,多向移动------------左下 两个方向上各移动4位 向左移动相当于+(-1,0) 向下移动相当于+(0,-1)

14(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2)

15(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2)

16(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2)

17(自上个节点:向上1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2)

18(自上个节点:向下1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2) 18(-2,1)

19(自上个节点:向下1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2) 18(-2,1) 19_(-2,0)

20(自上个节点:向下1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2) 18(-2,1) 19_(-2,0) 20_(-2,-1)

21(自上个节点:向下1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2) 18(-2,1) 19_(-2,0) 20_(-2,-1) 21_(-2,-2)

第5次,多向移动------------右上 两个方向上各移动5位 向右移动相当于+(1,0) 向上移动相当于+(0,1)

22(自上个节点:向左1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2) 18(-2,1) 19_(-2,0) 20_(-2,-1) 21_(-2,-2) 22_(-1,-2)

23(自上个节点:向左1位): 1_(0,0) 2_(1,0) 3_(1,1) 4_(0,1) 5_(-1,1) 6_(-1,0) 7_(-1,-1) 8_(0,-1) 9_(1,-1) 10_(2,-1) 11_(2,0) 12_(2,1) 13_(2,2) 14_(1,2) 15_(0,2) 16_(-1,2) 17_(-2,2) 18(-2,1) 19_(-2,0) 20_(-2,-1) 21_(-2,-2) 22_(-1,-2) 23_(0,-2)

.

.

.

.

由以上规律可以看出,从1值点开始,我们按照 右->上->左->下 开始漫游,当漫游到当前方向的最后一个位置时候,换下一个方向继续漫游

'''

import collections

#定义坐标表示

Position=collections.namedtuple('Position','x y')

#节点对象

class Node:

#初始化 设置节点的值

def __init__(self,val):

self.val=val #设置 Node 节点的值

#设置坐标值

def set_position(self,position):

self.position=position

def __repr__(self):

return "{}_({},{})".format(self.val,self.position.x,self.position.y)

def __str__(self):

return self.__str__()

#根据当前漫游方向获取接下来漫游的方向 按照: 右 上 左 下 的方向循环

def get_direction(direction_index):

if direction_index<=2:

result=direction_index+1

if direction_index==3:

result=0

return result

#根据输入的值n,创建从1到n的n个节点,返回各个节点组成的字典

def generate_nodes(n):

#存放结果集合

result_dict={}

#向各个方向移动需要变更的节点位置值

direction_move_list=[(1,0),(0,1),(-1,0),(0,-1)] #方向: 右 上 左 下

#判断1个特殊情况,n=1时

result_dict[1]=Node(1)

result_dict[1].position=Position(0,0)

if n==1:

#直接返回结果

return result_dict

#开始漫游并创建漫游到的节点

current_n=1 #记录当前漫游到的节点

#记录第几次多向移动(这个定义结合上面的分析) 多向移动的次数

movie_times=1

#控制漫游方向变化

direction_index=0

while True:

for i in range(2):

#在这个方上已经移动的次数

direction_times=0

#定向漫游移动次数 小于 多向移动次数

while direction_times

#当前漫游到的节点的值等于输入的n则跳出

if current_n==n:

return result_dict

current_node=result_dict[current_n]

current_n+=1

result_dict[current_n]=Node(current_n) #创建漫游到的新节点

#新节点的x值 y值

x=current_node.position.x+direction_move_list[direction_index][0]

y=current_node.position.y+direction_move_list[direction_index][1]

result_dict[current_n].position=Position(x,y)

#定向移动步数加1

direction_times+=1

#换向

direction_index=get_direction(direction_index)

#移动次数加1

movie_times+=1

#测试输出1

def main_01():

display_01=[[" " for _ in range(9)] for _ in range(9)]

test_result_01=generate_nodes(9)

print(test_result_01)

basic_position=Position(4,4)

for key in test_result_01:

x,y=test_result_01[key].position.x+basic_position.x,(-1)*test_result_01[key].position.y+basic_position.y

display_01[y][x]="%4d"%key

for item in display_01:

print(item)

#测试输出2

def main_02():

display_01=[[" " for _ in range(9)] for _ in range(9)]

test_result_01=generate_nodes(23)

print(test_result_01)

basic_position=Position(4,4)

for key in test_result_01:

x,y=test_result_01[key].position.x+basic_position.x,(-1)*test_result_01[key].position.y+basic_position.y

display_01[y][x]="%4d"%key

for item in display_01:

print(item)

print('-*-'*100)

#测试输出3

def main_03():

display_01=[[" " for _ in range(9)] for _ in range(9)]

test_result_01=generate_nodes(1)

print(test_result_01)

basic_position=Position(4,4)

for key in test_result_01:

x,y=test_result_01[key].position.x+basic_position.x,(-1)*test_result_01[key].position.y+basic_position.y

display_01[y][x]="%4d"%key

for item in display_01:

print(item)

print('-*-'*100)

#测试输出3

def main_04():

display_01=[[" " for _ in range(9)] for _ in range(9)]

test_result_01=generate_nodes(78)

print(test_result_01)

basic_position=Position(4,4)

for key in test_result_01:

x,y=test_result_01[key].position.x+basic_position.x,(-1)*test_result_01[key].position.y+basic_position.y

display_01[y][x]="%4d"%key

for item in display_01:

print(item)

print('-*-'*100)

if __name__=="__main__":

main_01()

main_02()

main_03()

main_04()

'''

输出结果:

{1: 1_(0,0), 2: 2_(1,0), 3: 3_(1,1), 4: 4_(0,1), 5: 5_(-1,1), 6: 6_(-1,0), 7: 7_(-1,-1), 8: 8_(0,-1), 9: 9_(1,-1)}

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' 5', ' 4', ' 3', ' ', ' ', ' ']

[' ', ' ', ' ', ' 6', ' 1', ' 2', ' ', ' ', ' ']

[' ', ' ', ' ', ' 7', ' 8', ' 9', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

{1: 1_(0,0), 2: 2_(1,0), 3: 3_(1,1), 4: 4_(0,1), 5: 5_(-1,1), 6: 6_(-1,0), 7: 7_(-1,-1), 8: 8_(0,-1), 9: 9_(1,-1), 10: 10_(2,-1), 11: 11_(2,0), 12: 12_(2,1), 13: 13_(2,2), 14: 14_(1,2), 15: 15_(0,2), 16: 16_(-1,2), 17: 17_(-2,2), 18: 18_(-2,1), 19: 19_(-2,0), 20: 20_(-2,-1), 21: 21_(-2,-2), 22: 22_(-1,-2), 23: 23_(0,-2)}

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' 17', ' 16', ' 15', ' 14', ' 13', ' ', ' ']

[' ', ' ', ' 18', ' 5', ' 4', ' 3', ' 12', ' ', ' ']

[' ', ' ', ' 19', ' 6', ' 1', ' 2', ' 11', ' ', ' ']

[' ', ' ', ' 20', ' 7', ' 8', ' 9', ' 10', ' ', ' ']

[' ', ' ', ' 21', ' 22', ' 23', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

{1: 1_(0,0)}

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' 1', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']

-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

{1: 1_(0,0), 2: 2_(1,0), 3: 3_(1,1), 4: 4_(0,1), 5: 5_(-1,1), 6: 6_(-1,0), 7: 7_(-1,-1), 8: 8_(0,-1), 9: 9_(1,-1), 10: 10_(2,-1), 11: 11_(2,0), 12: 12_(2,1), 13: 13_(2,2), 14: 14_(1,2), 15: 15_(0,2), 16: 16_(-1,2), 17: 17_(-2,2), 18: 18_(-2,1), 19: 19_(-2,0), 20: 20_(-2,-1), 21: 21_(-2,-2), 22: 22_(-1,-2), 23: 23_(0,-2), 24: 24_(1,-2), 25: 25_(2,-2), 26: 26_(3,-2), 27: 27_(3,-1), 28: 28_(3,0), 29: 29_(3,1), 30: 30_(3,2), 31: 31_(3,3), 32: 32_(2,3), 33: 33_(1,3), 34: 34_(0,3), 35: 35_(-1,3), 36: 36_(-2,3), 37: 37_(-3,3), 38: 38_(-3,2), 39: 39_(-3,1), 40: 40_(-3,0), 41: 41_(-3,-1), 42: 42_(-3,-2), 43: 43_(-3,-3), 44: 44_(-2,-3), 45: 45_(-1,-3), 46: 46_(0,-3), 47: 47_(1,-3), 48: 48_(2,-3), 49: 49_(3,-3), 50: 50_(4,-3), 51: 51_(4,-2), 52: 52_(4,-1), 53: 53_(4,0), 54: 54_(4,1), 55: 55_(4,2), 56: 56_(4,3), 57: 57_(4,4), 58: 58_(3,4), 59: 59_(2,4), 60: 60_(1,4), 61: 61_(0,4), 62: 62_(-1,4), 63: 63_(-2,4), 64: 64_(-3,4), 65: 65_(-4,4), 66: 66_(-4,3), 67: 67_(-4,2), 68: 68_(-4,1), 69: 69_(-4,0), 70: 70_(-4,-1), 71: 71_(-4,-2), 72: 72_(-4,-3), 73: 73_(-4,-4), 74: 74_(-3,-4), 75: 75_(-2,-4), 76: 76_(-1,-4), 77: 77_(0,-4), 78: 78_(1,-4)}

[' 65', ' 64', ' 63', ' 62', ' 61', ' 60', ' 59', ' 58', ' 57']

[' 66', ' 37', ' 36', ' 35', ' 34', ' 33', ' 32', ' 31', ' 56']

[' 67', ' 38', ' 17', ' 16', ' 15', ' 14', ' 13', ' 30', ' 55']

[' 68', ' 39', ' 18', ' 5', ' 4', ' 3', ' 12', ' 29', ' 54']

[' 69', ' 40', ' 19', ' 6', ' 1', ' 2', ' 11', ' 28', ' 53']

[' 70', ' 41', ' 20', ' 7', ' 8', ' 9', ' 10', ' 27', ' 52']

[' 71', ' 42', ' 21', ' 22', ' 23', ' 24', ' 25', ' 26', ' 51']

[' 72', ' 43', ' 44', ' 45', ' 46', ' 47', ' 48', ' 49', ' 50']

[' 73', ' 74', ' 75', ' 76', ' 77', ' 78', ' ', ' ', ' ']

-*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*--*-

Process finished with exit code 0

'''

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值