Skip to content

Commit 8fd4b77

Browse files
committed
feat: Add solution for LeetCode #799
1 parent 30af5ad commit 8fd4b77

4 files changed

Lines changed: 140 additions & 0 deletions

File tree

SOLVED.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@
8888
| 740 | [Delete and Earn](https://leetcode.com/problems/delete-and-earn/) | [Code](src/leetcode/problems/delete-and-earn.cpp) / [Test](test/leetcode/problems/delete-and-earn.cpp) |
8989
| 744 | [Find Smallest Letter Greater Than Target](https://leetcode.com/problems/find-smallest-letter-greater-than-target/) | [Code](src/leetcode/problems/find-smallest-letter-greater-than-target.cpp) / [Test](test/leetcode/problems/find-smallest-letter-greater-than-target.cpp) |
9090
| 756 | [Pyramid Transition Matrix](https://leetcode.com/problems/pyramid-transition-matrix/) | [Code](src/leetcode/problems/pyramid-transition-matrix.cpp) / [Test](test/leetcode/problems/pyramid-transition-matrix.cpp) |
91+
| 799 | [Champagne Tower](https://leetcode.com/problems/champagne-tower/) | [Code](src/leetcode/problems/champagne-tower.cpp) / [Test](test/leetcode/problems/champagne-tower.cpp) |
9192
| 816 | [Ambiguous Coordinates](https://leetcode.com/problems/ambiguous-coordinates/) | [Code](src/leetcode/problems/ambiguous-coordinates.cpp) / [Test](test/leetcode/problems/ambiguous-coordinates.cpp) |
9293
| 829 | [Consecutive Numbers Sum](https://leetcode.com/problems/consecutive-numbers-sum/) | [Code](src/leetcode/problems/consecutive-numbers-sum.cpp) / [Test](test/leetcode/problems/consecutive-numbers-sum.cpp) |
9394
| 837 | [New 21 Game](https://leetcode.com/problems/new-21-game/) | [Code](src/leetcode/problems/new-21-game.cpp) / [Test](test/leetcode/problems/new-21-game.cpp) |
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#include "leetcode/core.h"
2+
3+
namespace leetcode {
4+
namespace problem_799 {
5+
6+
using Func = std::function<double(int, int, int)>;
7+
8+
class ChampagneTowerSolution : public SolutionBase<Func> {
9+
public:
10+
//! 799. Champagne Tower
11+
//! https://leetcode.com/problems/champagne-tower/
12+
double champagneTower(int poured, int query_row, int query_glass);
13+
14+
ChampagneTowerSolution();
15+
};
16+
17+
} // namespace problem_799
18+
} // namespace leetcode
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#include "leetcode/problems/champagne-tower.h"
2+
3+
namespace leetcode {
4+
namespace problem_799 {
5+
6+
// 模拟法:逐层计算每个杯子的香槟量
7+
// 用dp[i][j]表示第i行第j个杯子收到的总香槟量(可能超过1)
8+
// 如果dp[i][j] > 1,则溢出部分(dp[i][j] - 1) / 2分别流入下一行的两个杯子
9+
// 时间复杂度: O(query_row^2),空间复杂度: O(query_row)
10+
static double solution1(int poured, int query_row, int query_glass) {
11+
// 由于只需要前一行的数据,可以用一维数组优化空间
12+
// 但为了清晰,先用二维思路,用vector存储当前行
13+
vector<double> current_row(1, poured); // 第0行只有1个杯子,初始倒入poured
14+
15+
for (int row = 0; row < query_row; ++row) {
16+
vector<double> next_row(row + 2, 0.0); // 下一行有row+2个杯子
17+
for (int glass = 0; glass <= row; ++glass) {
18+
if (current_row[glass] > 1.0) {
19+
// 溢出部分平均分给下一行的左右两个杯子
20+
double overflow = (current_row[glass] - 1.0) / 2.0;
21+
next_row[glass] += overflow; // 左下方的杯子
22+
next_row[glass + 1] += overflow; // 右下方的杯子
23+
}
24+
}
25+
current_row = std::move(next_row);
26+
}
27+
28+
// 返回结果,但最多为1(杯子满了)
29+
return min(1.0, current_row[query_glass]);
30+
}
31+
32+
ChampagneTowerSolution::ChampagneTowerSolution() {
33+
setMetaInfo({.id = 799,
34+
.title = "Champagne Tower",
35+
.url = "https://leetcode.com/problems/champagne-tower/"});
36+
registerStrategy("Simulation", solution1);
37+
}
38+
39+
double ChampagneTowerSolution::champagneTower(int poured, int query_row, int query_glass) {
40+
return getSolution()(poured, query_row, query_glass);
41+
}
42+
43+
} // namespace problem_799
44+
} // namespace leetcode
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#include "leetcode/problems/champagne-tower.h"
2+
3+
#include "gtest/gtest.h"
4+
5+
namespace leetcode {
6+
namespace problem_799 {
7+
8+
class ChampagneTowerTest : public ::testing::TestWithParam<std::string> {
9+
protected:
10+
void SetUp() override { solution.setStrategy(GetParam()); }
11+
12+
ChampagneTowerSolution solution;
13+
};
14+
15+
TEST_P(ChampagneTowerTest, Example1) {
16+
// poured = 1, query_row = 1, query_glass = 1
17+
// 倒1杯到顶层,顶层满了,没有溢出,所以第1行第1个杯子是空的
18+
int poured = 1;
19+
int query_row = 1;
20+
int query_glass = 1;
21+
double expected = 0.0;
22+
EXPECT_DOUBLE_EQ(expected, solution.champagneTower(poured, query_row, query_glass));
23+
}
24+
25+
TEST_P(ChampagneTowerTest, Example2) {
26+
// poured = 2, query_row = 1, query_glass = 1
27+
// 倒2杯到顶层,顶层满1杯,溢出1杯,平均分给下一行两个杯子,各0.5杯
28+
int poured = 2;
29+
int query_row = 1;
30+
int query_glass = 1;
31+
double expected = 0.5;
32+
EXPECT_DOUBLE_EQ(expected, solution.champagneTower(poured, query_row, query_glass));
33+
}
34+
35+
TEST_P(ChampagneTowerTest, Example3) {
36+
// poured = 100000009, query_row = 33, query_glass = 17
37+
// 大量香槟,中间位置会满
38+
int poured = 100000009;
39+
int query_row = 33;
40+
int query_glass = 17;
41+
double expected = 1.0;
42+
EXPECT_DOUBLE_EQ(expected, solution.champagneTower(poured, query_row, query_glass));
43+
}
44+
45+
TEST_P(ChampagneTowerTest, ZeroPoured) {
46+
// 没有倒香槟,所有杯子都是空的
47+
int poured = 0;
48+
int query_row = 0;
49+
int query_glass = 0;
50+
double expected = 0.0;
51+
EXPECT_DOUBLE_EQ(expected, solution.champagneTower(poured, query_row, query_glass));
52+
}
53+
54+
TEST_P(ChampagneTowerTest, TopGlassFull) {
55+
// 倒1杯,顶层满了
56+
int poured = 1;
57+
int query_row = 0;
58+
int query_glass = 0;
59+
double expected = 1.0;
60+
EXPECT_DOUBLE_EQ(expected, solution.champagneTower(poured, query_row, query_glass));
61+
}
62+
63+
TEST_P(ChampagneTowerTest, SecondRowBothHalf) {
64+
// 倒2杯,第1行两个杯子各0.5
65+
int poured = 2;
66+
int query_row = 1;
67+
int query_glass = 0;
68+
double expected = 0.5;
69+
EXPECT_DOUBLE_EQ(expected, solution.champagneTower(poured, query_row, query_glass));
70+
}
71+
72+
INSTANTIATE_TEST_SUITE_P(
73+
LeetCode, ChampagneTowerTest,
74+
::testing::ValuesIn(ChampagneTowerSolution().getStrategyNames()));
75+
76+
} // namespace problem_799
77+
} // namespace leetcode

0 commit comments

Comments
 (0)