您可以使用蛮力O(n*2^n) 方法解决此问题:将您的点定义为一些类/结构,除了您的点的(x,y) 坐标外,它还包含一个布尔值mirrored 状态。对于n 点数,循环遍历这组点的所有2^n 可能状态集。对于每组状态,计算边界矩形的周长 (2x+2y)。
以下是在 Swift 中实现的解决方案。如果您选择使用这种蛮力方法,希望您可以将其翻译成您选择的语言。
点容器和帮助功能:
struct Point {
private var xOrig : Double
private var yOrig : Double
private var mirrored = false
var x : Double { return mirrored ? yOrig : xOrig }
var y : Double { return mirrored ? xOrig : yOrig }
init(_ x: Double, _ y: Double) {
xOrig = x
yOrig = y
}
mutating func setState(state: Bool) {
mirrored = state
}
}
func boundingBoxCircumference(points: [Point]) -> Double {
let xMax = points.maxElement { $0.x < $1.x }?.x ?? 0.0
let xMin = points.minElement { $0.x < $1.x }?.x ?? 0.0
let yMax = points.maxElement { $0.y < $1.y }?.y ?? 0.0
let yMin = points.minElement { $0.y < $1.y }?.y ?? 0.0
return 2*((xMax - xMin) + (yMax - yMin))
}
func setMirroredStates(inout points: [Point], states: [Bool]) {
for i in 0..<points.count {
points[i].setState(states[i])
}
}
主要功能及示例
func findSmallestBox(var points: [Point]) -> Double {
var smallestBox = Double.infinity
for i in 0..<Int(pow(2,Double(points.count))) {
smallestBox = min(smallestBox, boundingBoxCircumference(points))
var binString = String(i, radix: 2)
if let a = Optional(points.count - binString.characters.count) where a > 0 {
binString = "".stringByPaddingToLength(a, withString: "0", startingAtIndex: 0) + binString
}
let pointStates = Array(binString.characters).map { String($0) == "1" }
setMirroredStates(&points, states: pointStates)
}
return smallestBox
}
var myPoints : [Point] = [Point(1,2), Point(-4,3), Point(7,-5), Point(5,4), Point(-5, -1)]
print(findSmallestBox(myPoints)) // 34