Re: [閒聊] 每日leetcode

看板Marginalman作者 (神楽めあ的煙灰缸)時間15小時前 (2026/01/14 21:33), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1563/1563 (看更多)
哎喲 我肏 這題怎麼這麼難, 寫到現在 幹幹幹 3454. Separate Squares II 跟昨天不同, 今天的題目, 重疊的面積只能算一次 思路 : 用segment tree紀錄目前x軸累積的寬度 首先把每個正方形拆成兩個平行x軸的邊稱為上邊、下邊 並且以[x1,x2,y,k]的形式記錄起來, 其中k是用來記錄這是上邊還是下邊 並且依照y的大小排序 當遇到下邊時, 要把下邊這段長度(x2-x1)加到累積寬度裡 反之遇到上邊, 要把上邊的長度扣掉 就這樣遍歷所有邊 每次都將 累積的寬度*(目前邊的y-上一條邊的y) 加到面積裡 算出總面積後 再從頭算一次 這次算到面積 >= 總面積的一半後 將 目前的y - ( 目前的面積 - 總面積的一半後 ) / 累積寬度就是答案 golang code : type Node struct { l, r int k int length int } type SegmentTree struct { nums []int tree []Node } func newTree(nums []int) *SegmentTree { n := len(nums) t := make([]Node, 4*n) s := &SegmentTree{ nums: nums, tree: t, } s.build(0, 0, n-1) return s } func (t *SegmentTree) build(u, l, r int) { t.tree[u].l = l t.tree[u].r = r if l != r { mid := l + (r-l)/2 t.build(u*2+1, l, mid) t.build(u*2+2, mid+1, r) } } func (t *SegmentTree) modify(u, l, r, k int) { if t.tree[u].l > r || t.tree[u].r < l { return } if l <= t.tree[u].l && t.tree[u].r <= r { t.tree[u].k += k } else { mid := t.tree[u].l + (t.tree[u].r-t.tree[u].l)/2 if l <= mid { t.modify(u*2+1, l, r, k) } if r > mid { t.modify(u*2+2, l, r, k) } } if t.tree[u].k > 0 { t.tree[u].length = t.nums[t.tree[u].r+1] - t.nums[t.tree[u].l] } else if t.tree[u].l == t.tree[u].r { t.tree[u].length = 0 } else { t.tree[u].length = t.tree[u*2+1].length + t.tree[u*2+2].length } } func (t *SegmentTree) query() int { return t.tree[0].length } func separateSquares(squares [][]int) float64 { n := len(squares) events := make([][]int, 0, 2*n) xs := make([]int, 0) recX := make(map[int]bool) for i := 0; i < n; i++ { x1, y1, l := squares[i][0], squares[i][1], squares[i][2] x2, y2 := x1+l, y1+l events = append(events, []int{x1, x2, y1, 1}) events = append(events, []int{x1, x2, y2, -1}) if !recX[x1] { recX[x1] = true xs = append(xs, x1) } if !recX[x2] { recX[x2] = true xs = append(xs, x2) } } slices.Sort(xs) slices.SortFunc(events, func(a, b []int) int { return a[2] - b[2] }) st := newTree(xs) area, y0 := 0.0, 0 posX := make(map[int]int) for i, val := range xs { posX[val] = i } for _, event := range events { x1, x2, y, k := event[0], event[1], event[2], event[3] width := st.query() area += float64((y - y0) * width) st.modify(0, posX[x1], posX[x2]-1, k) y0 = y } target := area / 2.0 area = 0.0 for _, event := range events { x1, x2, y, k := event[0], event[1], event[2], event[3] width := st.query() area += float64((y - y0) * width) st.modify(0, posX[x1], posX[x2]-1, k) if area >= target { return float64(y) - (area-target)/float64(width) } y0 = y } return 0.0 } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 203.121.235.241 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/Marginalman/M.1768397599.A.FD2.html
文章代碼(AID): #1fPviV_I (Marginalman)
討論串 (同標題文章)
文章代碼(AID): #1fPviV_I (Marginalman)