package main import ( "bufio" "fmt" "math" "math/cmplx" "os" "strconv" ) var sc = bufio.NewScanner(os.Stdin) func main() { sc.Split(bufio.ScanWords) var ps []complex128 for i := 0; i < 5; i++ { ps = append(ps, complex(nextFloat(), nextFloat())) } if len(solve2(ps)) == 5 { fmt.Println("YES") return } fmt.Println("NO") } func nextLine() string { sc.Scan() return sc.Text() } func nextInt() int { i, _ := strconv.Atoi(nextLine()) return i } func solve2(ps []complex128) []complex128 { lp, rp := leftMost(ps), rightMost(ps) ret := make([]complex128, 2, 500) ret[0], ret[1] = lp, rp return append(ret, solve(lp, rp, ps)...) } func solve(lp, rp complex128, ps []complex128) []complex128 { if len(ps) == 0 { return nil } a, b, c := equationL(lp, rp) updown, div := [][]complex128{make([]complex128, 0, 50), make([]complex128, 0, 50)}, make([]complex128, 2) maxU, maxD := float64(0), float64(0) ret := make([]complex128, 0, 100) for _, p := range ps { d := distance(a, b, c, p) switch side := posL(p, lp, rp); { case side > 0: if d > maxU { maxU, div[0] = d, p } updown[0] = append(updown[0], p) case side < 0: if d > maxD { maxD, div[1] = d, p } updown[1] = append(updown[1], p) } } if len(updown[0]) > 0 { ret = append(ret, div[0]) } if len(updown[1]) > 0 { ret = append(ret, div[1]) } left := [][]complex128{updown[0][:0], updown[1][:0]} right := [][]complex128{make([]complex128, 0, 25), make([]complex128, 0, 25)} tri := [][]complex128{[]complex128{lp, rp, div[0]}, []complex128{lp, rp, div[1]}} inter := []complex128{nearestP(div[0], lp, rp), nearestP(div[1], lp, rp)} for i := 0; i < 2; i++ { for _, p := range updown[i] { if inPolygon(p, tri[i]) { continue } if posL(p, inter[i], div[i]) > 0 { left[i] = append(left[i], p) continue } right[i] = append(right[i], p) } } ret = append(ret, solve(lp, div[0], left[0])...) ret = append(ret, solve(div[0], rp, right[0])...) ret = append(ret, solve(rp, div[1], left[1])...) ret = append(ret, solve(div[1], lp, right[1])...) return ret } func leftMost(ps []complex128) complex128 { p := ps[0] for _, v := range ps[1:] { if real(v) < real(p) { p = v } } return p } func rightMost(ps []complex128) complex128 { p := ps[0] for _, v := range ps[1:] { if real(v) > real(p) { p = v } } return p } func equationL(a, b complex128) (float64, float64, float64) { return imag(b) - imag(a), real(a) - real(b), imag(a)*real(b) - real(a)*imag(b) } func distance(a, b, c float64, z complex128) float64 { return math.Abs(a*real(z)+b*imag(z)+c) / math.Sqrt(a*a+b*b) } func posL(p, a, b complex128) int { ba, pa := b-a, p-a c := real(ba)*imag(pa) - imag(ba)*real(pa) switch { case c > 0: return 1 // left case c < 0: return -1 // right default: return 0 // on the line } } func nearestP(p, a, b complex128) complex128 { ab, ba, pa, pb := a-b, b-a, p-a, p-b if dot(ba, pa) < 0 { return a } if dot(ab, pb) < 0 { return b } return a + complex(dot(pa, ba)/(real(ba)*real(ba)+imag(ba)*imag(ba)), 0)*ba } func dot(a, b complex128) float64 { return real(a * cmplx.Conj(b)) } func inPolygon(p complex128, ps []complex128) bool { ps = append(ps, ps[0]) sign := posL(p, ps[0], ps[1]) for i, v := range ps[1 : len(ps)-1] { if sign*posL(p, v, ps[i+2]) < 0 { return false } } return true } func nextFloat() float64 { f, _ := strconv.ParseFloat(nextLine(), 64) return f }