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. POJ1061青蛙的约会(扩展欧几里德算法)

    青蛙的约会 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 102239   Accepted: 19781 Descript ...

  2. c语言0 ‘0’ '\0'空格都是什么玩意儿

    void main() { ; '; printf("\n%d,%c",ch,ch);//按照%d就是求编号,按照字符 printf("\n[%d],[%c]" ...

  3. 第32讲 UI组件之 时间日期控件DatePicker和TimePicker

    第32讲 UI组件之 时间日期控件DatePicker和TimePicker 在Android中,时间日期控件相对来说还是比较丰富的.其中, DatePicker用来实现日期输入设置,    Time ...

  4. poj 2836 Rectangular Covering(状态压缩dp)

    Description n points are given on the Cartesian plane. Now you have to use some rectangles whose sid ...

  5. 转:TestLink1.9.3测试用例:Excel转换XML工具<二>实现代码

    TestLink1.9.3测试用例:Excel转换XML工具<二>实现代码 http://blog.csdn.net/candle806/article/details/7490599 以 ...

  6. 关闭归档提示:ORA-38774: cannot disable media recovery - flashback database is enabled

    SQL> select * from v$version; Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit P ...

  7. java基础之数组

    数组的定义 数组的应用 1, 2, 3, 4,

  8. My way on Linux - [虚拟化&云计算] - 云计算概述&KVM虚拟化基础

    思维导图

  9. 用CSS3写的钟表

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  10. 纯CSS实现带小角的对话框式下拉菜单

    最近公司首页样式重写,头部下拉菜单改为了带小角的对话框式下拉菜单: 很多人可能会用图片,事实上纯CSS就能够实现: HTML: <!DOCTYPE html> <html lang= ...