矩形房间,带有英雄和敌人拼图的反射墙

时间:2017-04-27 14:57:28

标签: python-2.6

现状

过去9天,8/10测试用例通过时,我坚持使用Google foobar问题。有人可以帮我解决我的代码有什么问题吗?

问题陈述

哦 - 哦 - 你被一名兰达斯指挥官精英守卫逼到了!幸运的是,当你穿过火车站时,你从一个废弃的护柱上抓起了一把光束武器,所以你有机会战胜你的出路。但是光束武器对你和精英守卫都有潜在的危险:它的光束反射在墙壁上,这意味着你必须非常小心你射击以避免向自己弹射!

幸运的是,光束只能行进一定的最大距离才能变得太弱而不会造成伤害。你也知道如果一个光束撞到一个角落,它将以完全相同的方向反弹。当然,如果光束击中你或者后卫,它会立即停止(虽然很痛苦)。

写一个函数答案(尺寸,your_position,guard_position,distance),它给出了房间宽度和高度的2个整数数组,房间中x和y坐标的2个整数数组,在房间内有两个守卫&sx和y坐标的整数,并返回一个不同方向的整数,你可以发射这些方向以击中精英守卫,给定光束可以行进的最大距离。

房间具有整数尺寸[1&lt; 1]。 x_dim&lt; = 1000,1&lt; y_dim&lt; = 1000]。你和精英守卫都位于房间内不同的不同位置(x,y)的整数点阵上,使得[0&lt; x&lt; x_dim,0&lt; y&lt; y_dim。最后,光束在变为无害之前可以行进的最大距离将以整数1 <1表示。距离&lt; = 10000。

例如,如果你和精英守卫被安置在一个尺寸为[3,2],you_position [1,1],guard_position [2,1]和最大射击距离为4的房间里,你可以拍摄在七个不同的方向击中精英守卫(从你的位置给出矢量轴承):[1,0],[1,2],[1,-2],[3,2],[3,-2] ,[ - 3,2]和[-3,-2]。作为具体的例子,方位[1,0]的射击是距离1的直线水平射击,方位[-3,-2]的射击从左壁反弹然后是底壁反弹,然后击中精英守卫。总射门距离为sqrt(13),并且在击中精英后卫之前,轴承[1,2]的射门在顶壁反弹,总射击距离为sqrt(5)。

推荐链接

This post gives a test case and it is passing in my solution

This post gives a GUI to understand the problem

我的方法

只要反射点位于距离源点的给定距离内,我就会在所有方向上反映矩形房间的镜像平面中的敌人位置。这将使反射平面中的敌方阵地成为源头的直线。该距离小于给定距离。生成这些点后,我会检查该列表中的任何点是否会使光束在击中敌人之前通过英雄。

Python中的代码

from math import *

BOTTOM_LEFT = (0,0)
TOP_RIGHT   = (0,0)
SOURCE      = (0,0)
TARGET      = (0,0)
DISTANCE    = 0
BOTTOM_RIGHT    = (0,0)
TOP_LEFT    = (0,0)

def answer(tr, src, bp, dist):
    global BOTTOM_LEFT
    BOTTOM_LEFT = (0,0)
    global TOP_RIGHT
    TOP_RIGHT = tr
    global SOURCE
    SOURCE = src
    global TARGET
    TARGET = bp
    global DISTANCE
    DISTANCE = dist
    global BOTTOM_RIGHT
    BOTTOM_RIGHT = (TOP_RIGHT[0], BOTTOM_LEFT[1])
    global TOP_LEFT
    TOP_LEFT = (BOTTOM_LEFT[0], TOP_RIGHT[1])
    all_targets = get_targets(start_point = TARGET, distance = DISTANCE)
    CORNERS = [BOTTOM_LEFT, BOTTOM_RIGHT, TOP_LEFT, TOP_RIGHT]
    corner_angles = [4]
    i = 0
    while i < 4:
        ca = degrees(atan2(CORNERS[i][1] - SOURCE[1], CORNERS[i][0] - SOURCE[0]))
        corner_angles.append(ca)
        i = i+1
    valid_angles = set()
    for tgt in all_targets:
        pa = degrees(atan2(tgt[1] - SOURCE[1], tgt[0] - SOURCE[0]))
        if(tgt[0] - SOURCE[0] > 0 ):
            valid_angles.add(pa)
        elif(tgt[0] - SOURCE[0] < 0):
            if pa % 45 != 0 and pa not in corner_angles:
                valid_angles.add(pa)
        else:
            valid_angles.add(pa)
    if(src == bp):
        return 0
    else:
        return len(valid_angles)

def get_mirrored(point):
    ret = []
    x = point[0]
    y = point[1] - 2*(point[1] - TOP_RIGHT[1])
    ret.append((x,y))
    ret.append((point[0], point[1] - 2*(point[1] - BOTTOM_LEFT[1])))
    ret.append((point[0] - 2*(point[0] - BOTTOM_LEFT[0]), point[1]))
    ret.append((point[0] - 2*(point[0] - TOP_RIGHT[0]), point[1]))
    return ret

def get_targets(start_point, distance):
    targets = []
    targets.append(start_point)
    all_targets = set()
    all_targets.add((start_point[0],start_point[1]))
    last_targets = all_targets
    while True:
        new_level_targets = set()
        for tgt in last_targets:
            new_targets = get_mirrored(tgt)
            new_targets = set(t for t in new_targets if hypot(SOURCE[0] - t[0], SOURCE[1] - t[1]) <= DISTANCE)
            new_targets -= all_targets
            new_level_targets |= new_targets
        if not new_level_targets:
            break
        all_targets |= new_level_targets
        last_targets = new_level_targets
    return all_targets

print(answer((3,2), (1,1), (2,1), 4)) #Answer 7
print(answer((300,275), (150,150), (185,100), 500) #Answer 9

0 个答案:

没有答案