我得到了以下作业:
给定一个由四种颜色的像素组成的图像。颜色对应于地形,敌人,盟友和墙壁。可以在任何坐标(一对整数)上投掷炸弹。您还可以提供以下信息:
r
- 炸弹的爆炸半径(以像素为单位,正整数)e
- 杀死敌人的分数a
- 杀死盟友的分数(例如
r = 10
,e = 1
,a = -2
)当炸弹落下时,在其爆炸半径内的所有敌人和盟友都会死亡,除非它们与炸弹之间有墙(即连接士兵与炸弹的非抗锯齿线穿过墙)。当炸弹落在墙上时,该特定像素的行为就像普通地形一样。其余的墙仍然是墙。
您的初始分数为0。找到您应该丢下一枚炸弹以获得最佳分数的坐标。如果有多种最优解,则返回其中任何一种。
以下是一个裁剪,调整大小并更改颜色以提高可读性的示例图像:
我得到的原始图像可以在此处找到。
我已经想出来的
我知道 brute-force 这个问题是一个糟糕的解决方案。当没有墙壁时,我想出了一种快速解决它的方法。以下是一些伪代码:
args Map, R, A, E
for (every Soldier)
create a Heightmap with dimensions of Map
zero-fill the Heightmap
on the Heightmap draw a filled circle of value 1 around Soldier with radius R
if (Soldier is Ally)
multiply Heightmap by A
else
multiply Heightmap by E
add all Heightmaps together
return coordinates of highest point in TotalHeightmap
当然,这个'snippet'可以被优化,但在这种形式下更易理解。通过用墙来限制高度图圆,可以将其扩展为完整的解决方案。绘制圆很简单,许多图像处理库都提供了绘制圆的函数,因此也许最好的方法是先绘制圆形,然后在它们上面绘制墙壁,并从中心填充圆形,停止在墙壁或圆形边界上。在实现时,我会检查性能。
如果没有限制圆形,我会这样做:
run the above code to get a TotalHeightmap
create empty PointList
for (every Point in TotalHeightmap)
create PointObject with properties:
Coordinates,
Height,
WallsFlag = False
add PointObject to PointList
sort PointList by descending Height
until (PointList[0].WallsFlag == True)
for (every Soldier in radius R from PointList[0])
if (Bresenham line connecting Soldier with PointList[0] intersects a Wall)
subtract (A if Soldier is Ally else E) from PointList[0].Height
set PointList[0].WallsFlag = True
sort PointList by descending Height
return PointList[0].Coordinates
只要敌人和盟友的分数都是非负的,那么它就可以运行,但这远非完美。为了解决这个问题,我可以循环遍历所有像素,但那会非常缓慢(我猜不会像蛮力搜索那么慢,但这听起来并不是一个好主意)。找到墙壁交点的方法似乎也比较简陋。
我正在寻找更加优雅且快速的解决方案。你如何解决这个问题?如果有帮助的话,我将使用Python和PIL实现它。
顺便说一句,我相信我的老师允许我在SO上发布这个问题,我甚至认为他期望我讨论并实现最佳解决方案。