zoukankan      html  css  js  c++  java
  • Square spiral

    Square spiral

    Nikola picks up a strange circuit board. All of its elements are connected in a spiral and it is possible to connect the neighboring elements vertically and horizontally.

    The map of the circuit consists of a series of square cells. The first element in the center is marked as 1, and continuing in a clockwise spiral, each other elements is marked in ascending order. On the map, you can move (connect cells) vertically and horizontally. You can help Nikola find the manhattan distance between any two elements on the map. For example, the distance between cells 1 and 9 is two moves and the distance between 24 and 9 is one move.

    Input: Two marks of cells as an integers.

    Output: The manhattan distance between the two cells as an integer.

    原题链接:http://www.checkio.org/mission/strange-curcuit/

    题目大义:找出两点在图上的曼哈顿距离

    思路:首先观察得到,图中的数字由边数为2,4,6,8...的子正方形组成,而每个子正方形的数字个数有通项公式,为8*n + 4,如[1, 2, 3, 4],[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],然后每个子正方形的最大数字的值可以通过累加子正方形的数字个数得到,为[4, 16, 36, ...]。有了子正方形最大数字序列后,可判断给定的点在几号子正方形上,并以该最大值作为坐标圆点,向左为x轴正向,向上为y轴正向,求出该点在该子正方形上的坐标。分别得到两点在相应子正方形中的坐标后,内侧子坐标加上两个子正方形的序号差即可统一坐标系,最后距离为abs(x1 - x2) + abs(y1 - y2)

     1 def search_for_subsquare(number, sub_square_max_numbers):
     2     mlen = len(sub_square_max_numbers)
     3     for i in range(mlen):
     4         if number <= sub_square_max_numbers[i]:
     5             return i
     6 
     7 def cal_relative_position(sub_square_line_number, max_number_in_sub_square, number):
     8     pos = [0, 0]
     9 
    10     itr_number = max_number_in_sub_square
    11 
    12     if itr_number == number:
    13         return pos
    14 
    15     direction = [1, 0, 1, 0] #up left down right
    16     move = [1, 1, -1, -1] #+ + - -
    17 
    18     for pos_mv, each_dir in enumerate(direction):
    19         for i in range(sub_square_line_number - 1): #range(4) means range(0, 4)
    20             itr_number -= 1
    21             pos[each_dir] += move[pos_mv]
    22             if itr_number == number:
    23                 return pos
    24 
    25 
    26 def find_distance(first, second):
    27     sub_square_number_counts = [(8 * n + 4) for n in range(64)]
    28 
    29     sub_square_max_numbers = [4]
    30 
    31     len_count = len(sub_square_number_counts)
    32 
    33     for i in range(1, len_count):
    34         sub_square_max_numbers.append(sub_square_max_numbers[i - 1] + sub_square_number_counts[i])
    35 
    36     #search first and second in which sub_square
    37     first_square = search_for_subsquare(first, sub_square_max_numbers)
    38     second_square = search_for_subsquare(second, sub_square_max_numbers)
    39 
    40     #cal relative position in its sub_square
    41     pos_first = cal_relative_position((first_square + 1) * 2, sub_square_max_numbers[first_square], first)
    42     pos_second = cal_relative_position((second_square + 1) * 2, sub_square_max_numbers[second_square], second)
    43 
    44     #unify relative postition and cal manhatan dist
    45     if first_square > second_square:
    46         scale = first_square - second_square
    47         pos_second[0] += scale
    48         pos_second[1] += scale
    49     else:
    50         scale = second_square - first_square
    51         pos_first[0] += scale
    52         pos_first[1] += scale
    53 
    54     return abs(pos_first[0] - pos_second[0]) + abs(pos_first[1] - pos_second[1])

    review Sim0000's codes

     1 from math import sqrt
     2  
     3 # calculate the coordinate of n
     4 def coord(n):
     5     if n == 1: return (0, 0)
     6     r = int(sqrt(n - 1) - 1) // 2 + 1
     7     g, d = divmod(n - (2*r-1)**2 - 1, 2*r)
     8     return [(-r+d+1, r), (r, r-d-1), (r-d-1, -r), (-r, -r+d+1)][g]
     9  
    10 def find_distance(first, second):
    11     x1, y1 = coord(first)
    12     x2, y2 = coord(second)
    13     return abs(x2 - x1) + abs(y2 - y1)
    14  
    15     # At first, we determine ring which include n
    16     #   ring 0 : 1
    17     #   ring 1 : 2,3,...,9
    18     #   ring 2 : 10,11,...,25
    19     #   ring r : (2*r-1)**2+1,...,(2*r+1)**2
    20     # Using following formula, we can calculate r from n.
    21     #   r = int((sqrt(n - 1) - 1) / 2) + 1
    22     # Ring r have 8*r elements and start position is (-r+1, r).
    23     # And another interesting position is follows.
    24     #   (-r,  r) : left upper corner,  n = (2*r-1)**2 + 8*r = (2*r+1)**2
    25     #   ( r,  r) : right upper corner, n = (2*r-1)**2 + 2*r
    26     #   ( r, -r) : right lower corner, n = (2*r-1)**2 + 4*r
    27     #   (-r, -r) : left lower corner,  n = (2*r-1)**2 + 6*r
    28     #
    29     # Second, I divide ring into 4 groups corresponding to the direction.
    30     # Each group size is 2*r. The group 0 is the first 2*r elements of the ring
    31     # and its direction is right, and so on.
    32     #   group 0 (dir = R) : n is from (2*r-1)**2    +1 to (2*r-1)**2+2*r
    33     #   group 1 (dir = D) : n is from (2*r-1)**2+2*r+1 to (2*r-1)**2+4*r
    34     #   group 2 (dir = L) : n is from (2*r-1)**2+4*r+1 to (2*r-1)**2+6*r
    35     #   group 3 (dir = U) : n is from (2*r-1)**2+6*r+1 to (2*r-1)**2+8*r
    36     # Using following formula, we can calculate group number g from n, r.
    37     #   g = int((n - (2*r-1)**2 - 1) / (2*r)
    38     #
    39     # Finally, using above information, we will calulate the coordinate of n.
    40     # When n belongs to group 0 of ring r, then the coordinate of n is
    41     # (-r+1 + d, r), where d means n is the d-th elements of the group.
    42     # As well, we can calculate for another groups.
    43     #   group 0 : (-r+1+d, r)
    44     #   group 1 : (r, r-1+d)
    45     #   group 2 : (r-1-d, r)
    46     #   group 3 : (-r, -r+d+1)

    用的是数学方法,有时间再仔细看了

  • 相关阅读:
    【SpringBoot学习笔记】无法解析parent POM——1.5.3.RELEASE
    【WPF学习日记——[DevExpress]】GridControl 行中使用按钮
    【Web学习日记】——C#引用WebService,从配置文件改变引用地址
    【Web学习日记】——在IIS上发布一个WebService
    【WPF学习日记】——Window的DataContext绑定ViewModel
    使用kubectl管理k8s集群
    使用Kubeadm创建k8s集群之节点部署
    使用Kubeadm创建k8s集群之部署规划
    kubernetes运维
    linux常用命令大全
  • 原文地址:https://www.cnblogs.com/hzhesi/p/3917384.html
Copyright © 2011-2022 走看看