-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path009.swift
More file actions
88 lines (72 loc) · 2.1 KB
/
009.swift
File metadata and controls
88 lines (72 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import Foundation
func readInt() -> Int {
Int(readLine()!)!
}
func readInts() -> [Int] {
readLine()!.split(separator: " ").map { Int(String($0))! }
}
let n = readInt()
var pos: [(x: Double, y: Double)] = []
for _ in 0..<n {
let xy = readInts()
pos.append((Double(xy[0]), Double(xy[1])))
}
func solve(b: Int) -> Double {
var angles: [Double] = []
for i in 0..<n {
if i == b {
continue
}
let dX = pos[i].x - pos[b].x
let dY = pos[i].y - pos[b].y
if dX == 0.0 {
angles.append(dY > 0.0 ? .pi / 2.0 : .pi * 3.0 / 2.0)
} else {
let a = atan(dY / dX)
if dX < 0.0 {
angles.append(a + .pi)
} else if dY < 0.0 {
angles.append(a + 2.0 * .pi)
} else {
angles.append(a)
}
}
}
angles.sort(by: <)
var retMin = Double.pi
for a in angles {
let target = a < .pi ? a + .pi : a - .pi
let bottom = 0
let top = angles.count - 1
var left = bottom - 1 //この値は調べることはない
var right = top + 1 //この値は調べることはない
while right - left > 1 { //最後は隣り合った2つになって抜ける
let mid = left + (right - left) / 2
if angles[mid] <= target {
left = mid
} else {
right = mid
}
}
let candidate1: Double
let candidate2: Double
if left == bottom - 1 {
candidate1 = target - (angles.last! - 2.0 * .pi)
} else {
candidate1 = target - angles[left]
}
if right == top + 1 {
candidate2 = (angles[0] + 2.0 * .pi) - target
} else {
candidate2 = angles[right] - target
}
retMin = min(retMin, candidate1, candidate2)
}
return .pi - retMin
}
var ans = 0.0
//点Bを選んで残りから最大角度を出す
for b in 0..<n {
ans = max(ans, solve(b: b))
}
print(ans / (2.0 * .pi) * 360.0)