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. Android AutoCompleteTextView和MultiAutoCompleteTextView使用

    Android AutoCompleteTextView和MultiAutoCompleteTextView的功能类似于百度或者Google在搜索栏输入信息的时候,弹出的与输入信息接近的提示信息: 它 ...

  2. spring与数据库之间的配置

    spring 配置数据源的三种方式 1.使用org.springframework.jdbc.datasource.DriverManagerDataSource配置文件: <bean id=& ...

  3. n%i之和

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1168 题意:给定一个n,注意这里n小于10^12,求 分析:早些时 ...

  4. SRM 588 D2 L2:GUMIAndSongsDiv2,冷静思考,好的算法简洁明了

    题目来源:http://community.topcoder.com/stat?c=problem_statement&pm=12707 算法决定一切,这道题目有很多方法解,个人认为这里 ve ...

  5. Difference between enabled and userInteractionEnabled properties

    I read through the documentation, and here are my findings. UIButton inherits from UIControl the boo ...

  6. mount USB Device(U disk) on crux based on vmware

    1. 在 /mnt 下建立一个名叫USB的文件夹,文件夹名自定 cd /mnt mkdir USB 2. 查看一下磁盘分区情况 fdisk –l 3. 插入U盘 4. 再次查看磁盘分区情况,对比第一次 ...

  7. css_day7

  8. 简单JS多级下拉框无刷新

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. asp net 编程问题 实现下一篇 和上一篇效果

    首先是access数据库,有一个名为news的表,里面有三个字段,分别为id,classid 和name 其中id为主键,classid可以重复 现在有以下数据: id classid name 1 ...

  10. 分享一个通用的分页SQL

    又很久没写博客,今天记录一个SQLserver通用分页存储过程(适用于SqlServer2000及以上版本) 1.支持连表 2.支持条件查询 USE [MYDB] GO /****** Object: ...