Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 4d8a34c

Browse files
feat: add solutions to lcp problem: No.30 (doocs#2294)
No.30.魔塔游戏
1 parent b45d0fe commit 4d8a34c

File tree

6 files changed

+244
-0
lines changed

6 files changed

+244
-0
lines changed

‎lcp/LCP 30. 魔塔游戏/README.md‎

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,143 @@
3131

3232
## 解法
3333

34+
### 方法一:贪心 + 优先队列(小根堆)
35+
36+
我们定义以下数据结构或变量,其中:
37+
38+
- 优先队列(小根堆) $q$:存储当前所有怪物房间的血量减少值,堆顶元素为血量减少值最大的怪物房间(也即是最小的负数)。
39+
- 血量 $blood$:存储当前的血量,初始时 $blood = 1$。
40+
- 操作次数 $ans$:存储已经进行的操作次数,初始时 $ans = 0$。
41+
- 临时变量 $v$:存储当前待减少的血量,初始时 $v = 0$。
42+
43+
我们按照房间编号升序遍历所有房间,对于当前遍历到的房间 $x,ドル如果 $x$ 为怪物房间,我们就将 $x$ 的血量减少值加入 $q$。然后,我们更新当前的血量 $blood,ドル即 $blood = blood + x$。如果此时 $blood \le 0,ドル说明当前的血量不足以通过当前房间,因此我们需要调整访问顺序,此时我们可以贪心地将 $q$ 中血量减少值最大的房间调整至访问顺序的末尾,即把它累加到临时变量 $v$ 上,然后将 $blood$ 增加对应的值,并将该房间从 $q$ 中弹出。
44+
45+
遍历结束后,我们需要更新当前的血量 $blood,ドル即 $blood = blood + v$。如果此时 $blood \le 0,ドル说明无法访问完所有房间,返回 $-1$。否则,返回 $ans$。
46+
47+
时间复杂度 $O(n \times \log n),ドル空间复杂度 $O(n),ドル其中 $n$ 为房间的数量。
48+
49+
<!-- tabs:start -->
50+
51+
```python
52+
class Solution:
53+
def magicTower(self, nums: List[int]) -> int:
54+
q = []
55+
blood = 1
56+
ans = v = 0
57+
for x in nums:
58+
if x < 0:
59+
heappush(q, x)
60+
blood += x
61+
if blood <= 0:
62+
ans += 1
63+
v += q[0]
64+
blood -= heappop(q)
65+
blood += v
66+
return -1 if blood <= 0 else ans
67+
```
68+
69+
```java
70+
class Solution {
71+
public int magicTower(int[] nums) {
72+
PriorityQueue<Integer> q = new PriorityQueue<>();
73+
long blood = 1, v = 0;
74+
int ans = 0;
75+
for (int x : nums) {
76+
if (x < 0) {
77+
q.offer(x);
78+
}
79+
blood += x;
80+
if (blood <= 0) {
81+
++ans;
82+
v += q.peek();
83+
blood -= q.poll();
84+
}
85+
}
86+
blood += v;
87+
return blood <= 0 ? -1 : ans;
88+
}
89+
}
90+
```
91+
92+
```cpp
93+
class Solution {
94+
public:
95+
int magicTower(vector<int>& nums) {
96+
priority_queue<int, vector<int>, greater<int>> q;
97+
int64_t blood = 1, v = 0;
98+
int ans = 0;
99+
for (int x : nums) {
100+
if (x < 0) {
101+
q.push(x);
102+
}
103+
blood += x;
104+
if (blood <= 0) {
105+
++ans;
106+
v += q.top();
107+
blood -= q.top();
108+
q.pop();
109+
}
110+
}
111+
blood += v;
112+
return blood <= 0 ? -1 : ans;
113+
}
114+
};
115+
```
116+
117+
```go
118+
func magicTower(nums []int) (ans int) {
119+
q := hp{}
120+
blood, v := 1, 0
121+
for _, x := range nums {
122+
if x < 0 {
123+
heap.Push(&q, x)
124+
}
125+
blood += x
126+
if blood <= 0 {
127+
ans++
128+
t := heap.Pop(&q).(int)
129+
v += t
130+
blood -= t
131+
}
132+
}
133+
if blood+v <= 0 {
134+
return -1
135+
}
136+
return ans
137+
}
138+
139+
type hp struct{ sort.IntSlice }
140+
141+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
142+
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
143+
func (h *hp) Pop() any {
144+
a := h.IntSlice
145+
v := a[len(a)-1]
146+
h.IntSlice = a[:len(a)-1]
147+
return v
148+
}
149+
```
150+
151+
```ts
152+
function magicTower(nums: number[]): number {
153+
const q = new MinPriorityQueue();
154+
let [ans, blood, v] = [0, 1, 0];
155+
for (const x of nums) {
156+
if (x < 0) {
157+
q.enqueue(x);
158+
}
159+
blood += x;
160+
if (blood <= 0) {
161+
++ans;
162+
const t = q.dequeue().element;
163+
blood -= t;
164+
v += t;
165+
}
166+
}
167+
return blood + v <= 0 ? -1 : ans;
168+
}
169+
```
170+
171+
<!-- tabs:end -->
172+
34173
<!-- end -->
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
class Solution {
2+
public:
3+
int magicTower(vector<int>& nums) {
4+
priority_queue<int, vector<int>, greater<int>> q;
5+
int64_t blood = 1, v = 0;
6+
int ans = 0;
7+
for (int x : nums) {
8+
if (x < 0) {
9+
q.push(x);
10+
}
11+
blood += x;
12+
if (blood <= 0) {
13+
++ans;
14+
v += q.top();
15+
blood -= q.top();
16+
q.pop();
17+
}
18+
}
19+
blood += v;
20+
return blood <= 0 ? -1 : ans;
21+
}
22+
};

‎lcp/LCP 30. 魔塔游戏/Solution.go‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
func magicTower(nums []int) (ans int) {
2+
q := hp{}
3+
blood, v := 1, 0
4+
for _, x := range nums {
5+
if x < 0 {
6+
heap.Push(&q, x)
7+
}
8+
blood += x
9+
if blood <= 0 {
10+
ans++
11+
t := heap.Pop(&q).(int)
12+
v += t
13+
blood -= t
14+
}
15+
}
16+
if blood+v <= 0 {
17+
return -1
18+
}
19+
return ans
20+
}
21+
22+
type hp struct{ sort.IntSlice }
23+
24+
func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
25+
func (h *hp) Push(v any) { h.IntSlice = append(h.IntSlice, v.(int)) }
26+
func (h *hp) Pop() any {
27+
a := h.IntSlice
28+
v := a[len(a)-1]
29+
h.IntSlice = a[:len(a)-1]
30+
return v
31+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
class Solution {
2+
public int magicTower(int[] nums) {
3+
PriorityQueue<Integer> q = new PriorityQueue<>();
4+
long blood = 1, v = 0;
5+
int ans = 0;
6+
for (int x : nums) {
7+
if (x < 0) {
8+
q.offer(x);
9+
}
10+
blood += x;
11+
if (blood <= 0) {
12+
++ans;
13+
v += q.peek();
14+
blood -= q.poll();
15+
}
16+
}
17+
blood += v;
18+
return blood <= 0 ? -1 : ans;
19+
}
20+
}

‎lcp/LCP 30. 魔塔游戏/Solution.py‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
class Solution:
2+
def magicTower(self, nums: List[int]) -> int:
3+
q = []
4+
blood = 1
5+
ans = v = 0
6+
for x in nums:
7+
if x < 0:
8+
heappush(q, x)
9+
blood += x
10+
if blood <= 0:
11+
ans += 1
12+
v += q[0]
13+
blood -= heappop(q)
14+
blood += v
15+
return -1 if blood <= 0 else ans

‎lcp/LCP 30. 魔塔游戏/Solution.ts‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function magicTower(nums: number[]): number {
2+
const q = new MinPriorityQueue();
3+
let [ans, blood, v] = [0, 1, 0];
4+
for (const x of nums) {
5+
if (x < 0) {
6+
q.enqueue(x);
7+
}
8+
blood += x;
9+
if (blood <= 0) {
10+
++ans;
11+
const t = q.dequeue().element;
12+
blood -= t;
13+
v += t;
14+
}
15+
}
16+
return blood + v <= 0 ? -1 : ans;
17+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /