package q3454 import ( "math" "slices" ) type void struct{} func calcLengthAtY(squares [][]int) [][2]int { vertIdx := make([][2]int, len(squares)*2) for i := range squares { vertIdx[i*2] = [2]int{squares[i][1], i} vertIdx[i*2+1] = [2]int{squares[i][1] + squares[i][2], i} } slices.SortFunc(vertIdx, func(a, b [2]int) int { return a[0] - b[0] }) curSq := map[int]void{} curLenBuf := make([][2]int, len(squares)) calcLen := func() int { curLen := 0 curLenBuf = curLenBuf[:0] for i := range curSq { l := squares[i][0] r := l + squares[i][2] curLenBuf = append(curLenBuf, [2]int{l, r}) } slices.SortFunc(curLenBuf, func(a, b [2]int) int { return a[0] - b[0] }) r := math.MinInt for i := range curLenBuf { if curLenBuf[i][0] < r { curLen += max(0, curLenBuf[i][1]-r) } else { curLen += curLenBuf[i][1] - curLenBuf[i][0] } r = max(r, curLenBuf[i][1]) } return curLen } ret := make([][2]int, 0, len(squares)*2) for i := 0; i < len(vertIdx); { curY := vertIdx[i][0] for ; i < len(vertIdx) && vertIdx[i][0] == curY; i++ { sq := vertIdx[i][1] if _, ok := curSq[sq]; ok { delete(curSq, sq) } else { curSq[sq] = void{} } } ret = append(ret, [2]int{curY, calcLen()}) } return ret } func separateSquares(squares [][]int) float64 { lenAtY := calcLengthAtY(squares) totalArea := 0 for i := 0; i < len(lenAtY)-1; i++ { totalArea += lenAtY[i][1] * (lenAtY[i+1][0] - lenAtY[i][0]) } var area int for i := 0; i < len(lenAtY)-1; i++ { y, nextY := lenAtY[i][0], lenAtY[i+1][0] l := lenAtY[i][1] areaT := (nextY-y)*l + area switch { case areaT*2 == totalArea: return float64(nextY) case areaT*2 > totalArea: needed := float64(totalArea-area*2) / 2 return float64(y) + needed/float64(l) } area = areaT } return -1 } var _ = separateSquares