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. POJ3580---SuperMemo (Splay)

    各种操作,区间更新,求最值.翻转.插入.删除.当然是Splay这种神器了. 主要是 revolve这个操作,其实也就是3个区间翻转放到一块, 比如 REVOLVE x y T,T %= (y-x+1) ...

  2. [置顶] 使用struts拦截器+注解实现网络安全要求中的日志审计功能

    J2EE项目中出于安全的角度考虑,用户行为审计日志功能必不可少,通过本demo可以实现如下功能: 1.项目中记录审计日志的方法. 2.struts拦截器的基本配置和使用方法. 3.struts拦截器中 ...

  3. python ctypes小例子

    import time import ctypes import ctypes.wintypes SEE_MASK_NOCLOSEPROCESS = 0x00000040 SEE_MASK_INVOK ...

  4. UIScrollView使用autolayout 垂直滚动

    转自:http://dadage456.blog.163.com/blog/static/30310744201491141752716 1.创建一个空白的UIViewController .将UIS ...

  5. 开源 免费 java CMS - FreeCMS1.5-系统配置

    下载地址:http://code.google.com/p/freecms/ 系统配置 从FreeCMS 1.2 开始支持 管理系统使用的配置项. 从左侧管理菜单点击系统配置进入. 从FreeCMS ...

  6. Live555 实战之框架简单介绍

    作者:咕唧咕唧liukun321 来自:http://blog.csdn.net/liukun321 上一篇文章简要介绍了怎样以共享库的方式交叉编译Live555,今天再来介绍live源代码框架. 先 ...

  7. UITableView滑动按钮的操作

    一.开题  首先先创建工程, 创建工程的步骤就不一一介绍了, 前面有提过, 接下来是要在VC上创建一个tableview当然你也可以选择一个类继承于UITableView两者都可以, 这要看个人喜欢了 ...

  8. 标准I/O介绍

    标准I/O库 1. 标准I/O介绍 不仅是在UNIX系统中,很多操作系统上都实现了标准I/O库. 标准I/O库由ANSI C 标准说明 标准 I/O 库处理很多细节,例如带有缓冲分配.以优化长度执行的 ...

  9. Windows服务承载WCF

    Source文件 ------------------------- using System; using System.Collections.Generic; using System.Linq ...

  10. Android ----------获取各种路径(更新中。。。。。。)

    ##在手机中的路径 *获取应用的路径,形式:/data/data/包名 String appDataDir = getApplicationInfo().dataDir; *获取手机数据存储路径,即/ ...