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)

 def search_for_subsquare(number, sub_square_max_numbers):
mlen = len(sub_square_max_numbers)
for i in range(mlen):
if number <= sub_square_max_numbers[i]:
return i def cal_relative_position(sub_square_line_number, max_number_in_sub_square, number):
pos = [0, 0] itr_number = max_number_in_sub_square if itr_number == number:
return pos direction = [1, 0, 1, 0] #up left down right
move = [1, 1, -1, -1] #+ + - - for pos_mv, each_dir in enumerate(direction):
for i in range(sub_square_line_number - 1): #range(4) means range(0, 4)
itr_number -= 1
pos[each_dir] += move[pos_mv]
if itr_number == number:
return pos def find_distance(first, second):
sub_square_number_counts = [(8 * n + 4) for n in range(64)] sub_square_max_numbers = [4] len_count = len(sub_square_number_counts) for i in range(1, len_count):
sub_square_max_numbers.append(sub_square_max_numbers[i - 1] + sub_square_number_counts[i]) #search first and second in which sub_square
first_square = search_for_subsquare(first, sub_square_max_numbers)
second_square = search_for_subsquare(second, sub_square_max_numbers) #cal relative position in its sub_square
pos_first = cal_relative_position((first_square + 1) * 2, sub_square_max_numbers[first_square], first)
pos_second = cal_relative_position((second_square + 1) * 2, sub_square_max_numbers[second_square], second) #unify relative postition and cal manhatan dist
if first_square > second_square:
scale = first_square - second_square
pos_second[0] += scale
pos_second[1] += scale
else:
scale = second_square - first_square
pos_first[0] += scale
pos_first[1] += scale return abs(pos_first[0] - pos_second[0]) + abs(pos_first[1] - pos_second[1])

review Sim0000's codes

 from math import sqrt

 # calculate the coordinate of n
def coord(n):
if n == 1: return (0, 0)
r = int(sqrt(n - 1) - 1) // 2 + 1
g, d = divmod(n - (2*r-1)**2 - 1, 2*r)
return [(-r+d+1, r), (r, r-d-1), (r-d-1, -r), (-r, -r+d+1)][g] def find_distance(first, second):
x1, y1 = coord(first)
x2, y2 = coord(second)
return abs(x2 - x1) + abs(y2 - y1) # At first, we determine ring which include n
# ring 0 : 1
# ring 1 : 2,3,...,9
# ring 2 : 10,11,...,25
# ring r : (2*r-1)**2+1,...,(2*r+1)**2
# Using following formula, we can calculate r from n.
# r = int((sqrt(n - 1) - 1) / 2) + 1
# Ring r have 8*r elements and start position is (-r+1, r).
# And another interesting position is follows.
# (-r, r) : left upper corner, n = (2*r-1)**2 + 8*r = (2*r+1)**2
# ( r, r) : right upper corner, n = (2*r-1)**2 + 2*r
# ( r, -r) : right lower corner, n = (2*r-1)**2 + 4*r
# (-r, -r) : left lower corner, n = (2*r-1)**2 + 6*r
#
# Second, I divide ring into 4 groups corresponding to the direction.
# Each group size is 2*r. The group 0 is the first 2*r elements of the ring
# and its direction is right, and so on.
# group 0 (dir = R) : n is from (2*r-1)**2 +1 to (2*r-1)**2+2*r
# group 1 (dir = D) : n is from (2*r-1)**2+2*r+1 to (2*r-1)**2+4*r
# group 2 (dir = L) : n is from (2*r-1)**2+4*r+1 to (2*r-1)**2+6*r
# group 3 (dir = U) : n is from (2*r-1)**2+6*r+1 to (2*r-1)**2+8*r
# Using following formula, we can calculate group number g from n, r.
# g = int((n - (2*r-1)**2 - 1) / (2*r)
#
# Finally, using above information, we will calulate the coordinate of n.
# When n belongs to group 0 of ring r, then the coordinate of n is
# (-r+1 + d, r), where d means n is the d-th elements of the group.
# As well, we can calculate for another groups.
# group 0 : (-r+1+d, r)
# group 1 : (r, r-1+d)
# group 2 : (r-1-d, r)
# group 3 : (-r, -r+d+1)

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

Square spiral的更多相关文章

  1. 【Gym - 100947G】Square Spiral Search

    BUPT 2017 summer training (for 16) #1C 题意 A new computer scientist is trying to develop a new memory ...

  2. Project Euler:Problem 58 Spiral primes

    Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length ...

  3. 海龟绘图turtle模块的使用

    在本章中,我们将编写简短的.简单的程序来创建漂亮的.复杂的视觉效果.为了做到这一点,我们可以使用海龟作图软件.在海龟作图中,我们可以编写指令让一个虚拟的(想象中的)海龟在屏幕上来回移动.这个海龟带着一 ...

  4. 2015 AlBaath Collegiate Programming Contest(2月14日训练赛)

    A (By ggg): 题意:一个人还有x秒到红绿灯,这个红绿灯有g秒绿灯,y秒黄 灯,r秒红灯,问你到红绿灯的时候是什么灯.值得注意的是绿 灯变黄灯时,第g秒是黄灯了. B (By Anxdada) ...

  5. pyautogui介绍

    https://pyautogui.readthedocs.io/en/latest/introduction.html Introduction Purpose The purpose of PyA ...

  6. [LeetCode] Spiral Matrix II 螺旋矩阵之二

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  7. 【leetcode】Spiral Matrix II

    Spiral Matrix II Given an integer n, generate a square matrix filled with elements from 1 to n2 in s ...

  8. 【leetcode】Spiral Matrix II (middle)

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  9. Leetcode Spiral Matrix II

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

随机推荐

  1. Delphi 使用 Format格式话字符串的用法

    找出以前的代码,写个随笔, 又想起以前的公司和以前的同事来, 希望以前的公司和同事事事顺意. //返回格式化的字符串function TfrmLedgerExVoucherLoad.GetFormat ...

  2. HDU---4417Super Mario 树状数组 离线操作

    题意:给定 n个数,查询 位置L R内 小于x的数有多少个. 对于某一次查询 把所有比x小的数 ”的位置“ 都加入到树状数组中,然后sum(R)-sum(L-1)就是答案,q次查询就要离线操作了,按高 ...

  3. global.asax?app.config?webconfig??

    一.Global.asax 1.global.asax是什么? 一个文本文件,至于它包含写什么内容?顾名思义,global 肯定是掌管一个应用程序(application)的全局性的东西,例如应用程序 ...

  4. [转]notifyDataSetChanged() 动态更新ListView

    有时候我们需要修改已经生成的列表,添加或者修改数据,notifyDataSetChanged()可以在修改适配器绑定的数组后,不用重新刷新Activity,通知Activity更新ListView.今 ...

  5. mysql插入数据时,中文乱码

    MySQL 插入数据时,中文乱码问题的解决(转) 当向 MySQL 数据库插入一条带有中文的数据形如 insert into employee values(null,'张三','female','1 ...

  6. iOS之即时通讯相关理解

    Socket: 1>Socket又称"套接字" 2>网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 3>应用程序通常通 ...

  7. Hive2.0函数大全(中文版)

    摘要 Hive内部提供了很多函数给开发者使用,包括数学函数,类型转换函数,条件函数,字符函数,聚合函数,表生成函数等等,这些函数都统称为内置函数. 目录 数学函数 集合函数 类型转换函数 日期函数 条 ...

  8. Hibernate入门之关系篇:多对一和一对多映射

    关联关系映射,是对象映射关系中相对复杂的一种,但也是用处最多的一种,因为数据中的表不可能都是单独存在,彼此之间必定存在千丝万缕的联系,这也是关系型数据库的特征所在.同样关联关系的映射,也是对象关系映射 ...

  9. 事关Animation Tree的工作随笔(二)

    上回说到,游戏项目中客观会遇到逻辑状态的复杂性和动画状态的单一性之间的矛盾,那么Animation Tree是如何解决这个问题的呢? 这又需要引入一个定律:就是逻辑状态无论有多么复杂,但一套逻辑状态组 ...

  10. ngui点击与场景点击判断

    注:NGUI 组件上加上 BoxCollider 并设置区域大小 public void OnMouseDown()    { if (UICamera.hoveredObject == null) ...