-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathB24.go
More file actions
129 lines (103 loc) · 2.89 KB
/
Copy pathB24.go
File metadata and controls
129 lines (103 loc) · 2.89 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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// 以下は Go 1.20.6 を用いた解法です。
// **制約(N ≤ 100,000)に対応するため、計算量 O(N log N)** のアルゴリズム(2次元LIS)を使用しています。
// ソートと二分探索を使った効率的な処理で、型を明示し、関数分離も行っています。
// ---
// ## ✅ Go 実装(型明示・関数分離)
// ```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
"strconv"
"strings"
)
// Box は各箱の構造体。縦と横を持つ。
type Box struct {
X int // 縦の長さ
Y int // 横の長さ
}
// maxNestingDepth は最大で何重に箱をネストできるかを求める。
// @param boxes []Box - 各箱の情報
// @return int - 最大ネスト数
func maxNestingDepth(boxes []Box) int {
// X昇順、Xが同じならY降順でソート
sort.Slice(boxes, func(i, j int) bool {
if boxes[i].X == boxes[j].X {
return boxes[i].Y > boxes[j].Y
}
return boxes[i].X < boxes[j].X
})
// Y方向のLISを求める(O(N log N))
lis := make([]int, 0, len(boxes))
for _, box := range boxes {
y := box.Y
idx := lowerBound(lis, y)
if idx == len(lis) {
lis = append(lis, y)
} else {
lis[idx] = y
}
}
return len(lis)
}
// lowerBound は slice の中で target 以上の最小のインデックスを返す。
// @param slice []int - 単調増加列
// @param target int - 探す値
// @return int - 最左位置(lower_bound)
func lowerBound(slice []int, target int) int {
left, right := 0, len(slice)
for left < right {
mid := (left + right) / 2
if slice[mid] < target {
left = mid + 1
} else {
right = mid
}
}
return left
}
// main は標準入力を読み込み、最大ネスト数を出力する。
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
n, _ := strconv.Atoi(scanner.Text())
boxes := make([]Box, n)
for i := 0; i < n && scanner.Scan(); i++ {
line := scanner.Text()
parts := strings.Fields(line)
x, _ := strconv.Atoi(parts[0])
y, _ := strconv.Atoi(parts[1])
boxes[i] = Box{X: x, Y: y}
}
result := maxNestingDepth(boxes)
fmt.Println(result)
}
// ## ✅ 計算量とメモリ使用量
// | 項目 | 値 |
// | ------ | ---------------------------------- |
// | 時間計算量 | `O(N log N)`(ソート + LIS) |
// | 空間計算量 | `O(N)`(LIS配列+入力配列) |
// | メモリ使用量 | 約 10〜15MB(N ≒ 100,000 のとき) |
// | 最大入力対応 | `N ≦ 100,000`、`X,Y ≦ 500,000` まで対応 |
// ---
// ## ✅ 実行例
// ### 入力:
// ```
// 5
// 30 50
// 10 30
// 40 10
// 50 20
// 40 60
// ```
// ### 出力:
// ```
// 3
// ```
// ---
// ## ✅ 解法ポイント
// * `sort.Slice()` で X昇順・Y降順の安定ソート
// * `lowerBound` による Y の LIS 構築(ネスト数=LISの長さ)
// * Go のスライスを活かした効率的実装