From c2eeec3c6a4ba5df47964d488ac9fd4ee570889b Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Tue, 2 Dec 2025 21:36:04 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.3625 --- .../README.md | 252 +++++++++++++++++- .../README_EN.md | 252 +++++++++++++++++- .../Solution.cpp | 42 +++ .../Solution.go | 50 ++++ .../Solution.java | 43 +++ .../Solution.py | 42 +++ .../Solution.ts | 49 ++++ 7 files changed, 722 insertions(+), 8 deletions(-) create mode 100644 solution/3600-3699/3625.Count Number of Trapezoids II/Solution.cpp create mode 100644 solution/3600-3699/3625.Count Number of Trapezoids II/Solution.go create mode 100644 solution/3600-3699/3625.Count Number of Trapezoids II/Solution.java create mode 100644 solution/3600-3699/3625.Count Number of Trapezoids II/Solution.py create mode 100644 solution/3600-3699/3625.Count Number of Trapezoids II/Solution.ts diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/README.md b/solution/3600-3699/3625.Count Number of Trapezoids II/README.md index bb58483ae90b4..ca7d7cf8b5067 100644 --- a/solution/3600-3699/3625.Count Number of Trapezoids II/README.md +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/README.md @@ -79,32 +79,276 @@ tags: -### 方法一 +### 方法一:哈希表 + 枚举 + +我们可以把所有点两两组合,计算出每一对点所对应的直线的斜率和截距,并使用哈希表进行记录,计算斜率相同且截距不同的直线两两组合得到的数量之和。注意,对于平行四边形,我们在上述计算中会被重复计算两次,因此我们需要将其减去。 + +平行四边形的对角线中点重合,因此我们同样把所有点两两组合,计算出每一对点的中点坐标和斜率,并使用哈希表进行记录,计算斜率相同且中点坐标相同的点对两两组合得到的数量之和。 + +具体地,我们使用两个哈希表 $\textit{cnt1}$ 和 $\textit{cnt2}$ 分别记录以下信息: + +- 其中 $\textit{cnt1}$ 记录斜率 $k$ 和截距 $b$ 出现的次数,键为斜率 $k$,值为另一个哈希表,记录截距 $b$ 出现的次数; +- 其中 $\textit{cnt2}$ 记录点对的中点坐标和斜率 $k$ 出现的次数,键为点对的中点坐标 $p$,值为另一个哈希表,记录斜率 $k$ 出现的次数。 + +对于点对 $(x_1, y_1)$ 和 $(x_2, y_2)$,我们记 $dx = x_2 - x_1$,并且 $dy = y_2 - y_1$。如果 $dx = 0$,则说明两点在同一条垂直线上,我们记斜率 $k = +\infty$,截距 $b = x_1$;否则斜率 $k = \frac{dy}{dx}$,截距 $b = \frac{y_1 \cdot dx - x_1 \cdot dy}{dx}$。点对的中点坐标 $p$ 可以表示为 $p = (x_1 + x_2 + 2000) \cdot 4000 + (y_1 + y_2 + 2000)$,这里加上偏移量是为了避免负数。 + +接下来,我们遍历所有点对,计算出对应的斜率 $k$、截距 $b$ 和中点坐标 $p$,并更新哈希表 $\textit{cnt1}$ 和 $\textit{cnt2}$。 + +然后,我们遍历哈希表 $\textit{cnt1}$,对于每一个斜率 $k$,我们计算所有截距 $b$ 出现次数的两两组合之和,并累加到答案中。最后,我们遍历哈希表 $\textit{cnt2}$,对于每一个中点坐标 $p$,我们计算所有斜率 $k$ 出现次数的两两组合之和,并从答案中减去。 + +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 是点的数量。 #### Python3 ```python - +class Solution: + def countTrapezoids(self, points: List[List[int]]) -> int: + n = len(points) + + # cnt1: k -> (b -> count) + cnt1: dict[float, dict[float, int]] = defaultdict(lambda: defaultdict(int)) + # cnt2: p -> (k -> count) + cnt2: dict[int, dict[float, int]] = defaultdict(lambda: defaultdict(int)) + + for i in range(n): + x1, y1 = points[i] + for j in range(i): + x2, y2 = points[j] + dx, dy = x2 - x1, y2 - y1 + + if dx == 0: + k = 1e9 + b = x1 + else: + k = dy / dx + b = (y1 * dx - x1 * dy) / dx + + cnt1[k][b] += 1 + + p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000) + cnt2[p][k] += 1 + + ans = 0 + + for e in cnt1.values(): + s = 0 + for t in e.values(): + ans += s * t + s += t + + for e in cnt2.values(): + s = 0 + for t in e.values(): + ans -= s * t + s += t + + return ans ``` #### Java ```java - +class Solution { + public int countTrapezoids(int[][] points) { + int n = points.length; + Map> cnt1 = new HashMap<>(n * n); + Map> cnt2 = new HashMap<>(n * n); + + for (int i = 0; i < n; ++i) { + int x1 = points[i][0], y1 = points[i][1]; + for (int j = 0; j < i; ++j) { + int x2 = points[j][0], y2 = points[j][1]; + int dx = x2 - x1, dy = y2 - y1; + double k = dx == 0 ? Double.MAX_VALUE : 1.0 * dy / dx; + double b = dx == 0 ? x1 : 1.0 * (y1 * dx - x1 * dy) / dx; + if (k == -0.0) { + k = 0.0; + } + if (b == -0.0) { + b = 0.0; + } + cnt1.computeIfAbsent(k, _ -> new HashMap<>()).merge(b, 1, Integer::sum); + int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + cnt2.computeIfAbsent(p, _ -> new HashMap<>()).merge(k, 1, Integer::sum); + } + } + + int ans = 0; + for (var e : cnt1.values()) { + int s = 0; + for (int t : e.values()) { + ans += s * t; + s += t; + } + } + for (var e : cnt2.values()) { + int s = 0; + for (int t : e.values()) { + ans -= s * t; + s += t; + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int countTrapezoids(vector>& points) { + int n = points.size(); + unordered_map> cnt1; + unordered_map> cnt2; + + cnt1.reserve(n * n); + cnt2.reserve(n * n); + + for (int i = 0; i < n; ++i) { + int x1 = points[i][0], y1 = points[i][1]; + for (int j = 0; j < i; ++j) { + int x2 = points[j][0], y2 = points[j][1]; + int dx = x2 - x1, dy = y2 - y1; + double k = (dx == 0 ? 1e9 : 1.0 * dy / dx); + double b = (dx == 0 ? x1 : 1.0 * (1LL * y1 * dx - 1LL * x1 * dy) / dx); + + cnt1[k][b] += 1; + int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + cnt2[p][k] += 1; + } + } + + int ans = 0; + for (auto& [_, e] : cnt1) { + int s = 0; + for (auto& [_, t] : e) { + ans += s * t; + s += t; + } + } + for (auto& [_, e] : cnt2) { + int s = 0; + for (auto& [_, t] : e) { + ans -= s * t; + s += t; + } + } + return ans; + } +}; ``` #### Go ```go +func countTrapezoids(points [][]int) int { + n := len(points) + cnt1 := make(map[float64]map[float64]int, n*n) + cnt2 := make(map[int]map[float64]int, n*n) + + for i := 0; i < n; i++ { + x1, y1 := points[i][0], points[i][1] + for j := 0; j < i; j++ { + x2, y2 := points[j][0], points[j][1] + dx, dy := x2-x1, y2-y1 + + var k, b float64 + if dx == 0 { + k = 1e9 + b = float64(x1) + } else { + k = float64(dy) / float64(dx) + b = float64(int64(y1)*int64(dx)-int64(x1)*int64(dy)) / float64(dx) + } + + if cnt1[k] == nil { + cnt1[k] = make(map[float64]int) + } + cnt1[k][b]++ + + p := (x1+x2+2000)*4000 + (y1 + y2 + 2000) + if cnt2[p] == nil { + cnt2[p] = make(map[float64]int) + } + cnt2[p][k]++ + } + } + + ans := 0 + for _, e := range cnt1 { + s := 0 + for _, t := range e { + ans += s * t + s += t + } + } + for _, e := range cnt2 { + s := 0 + for _, t := range e { + ans -= s * t + s += t + } + } + return ans +} +``` +#### TypeScript + +```ts +function countTrapezoids(points: number[][]): number { + const n = points.length; + + const cnt1: Map> = new Map(); + const cnt2: Map> = new Map(); + + for (let i = 0; i < n; i++) { + const [x1, y1] = points[i]; + for (let j = 0; j < i; j++) { + const [x2, y2] = points[j]; + const [dx, dy] = [x2 - x1, y2 - y1]; + + const k = dx === 0 ? 1e9 : dy / dx; + const b = dx === 0 ? x1 : (y1 * dx - x1 * dy) / dx; + + if (!cnt1.has(k)) { + cnt1.set(k, new Map()); + } + const mapB = cnt1.get(k)!; + mapB.set(b, (mapB.get(b) || 0) + 1); + + const p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + + if (!cnt2.has(p)) { + cnt2.set(p, new Map()); + } + const mapK = cnt2.get(p)!; + mapK.set(k, (mapK.get(k) || 0) + 1); + } + } + + let ans = 0; + for (const e of cnt1.values()) { + let s = 0; + for (const t of e.values()) { + ans += s * t; + s += t; + } + } + for (const e of cnt2.values()) { + let s = 0; + for (const t of e.values()) { + ans -= s * t; + s += t; + } + } + + return ans; +} ``` diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/README_EN.md b/solution/3600-3699/3625.Count Number of Trapezoids II/README_EN.md index c55df4c8f7cbb..592f7c4ef872a 100644 --- a/solution/3600-3699/3625.Count Number of Trapezoids II/README_EN.md +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/README_EN.md @@ -76,32 +76,276 @@ tags: -### Solution 1 +### Solution 1: Hash Table + Enumeration + +We can combine all points pairwise, calculate the slope and intercept of the line corresponding to each pair of points, record them using a hash table, and calculate the sum of the number of pairs formed by lines with the same slope but different intercepts. Note that for parallelograms, we will count them twice in the above calculation, so we need to subtract them. + +The diagonals of a parallelogram share the same midpoint. Therefore, we also combine all points pairwise, calculate the midpoint coordinates and slope of each pair of points, record them using a hash table, and calculate the sum of the number of pairs formed by point pairs with the same slope and the same midpoint coordinates. + +Specifically, we use two hash tables $\textit{cnt1}$ and $\textit{cnt2}$ to record the following information: + +- $\textit{cnt1}$ records the number of occurrences of slope $k$ and intercept $b$, with the key being the slope $k$ and the value being another hash table that records the number of occurrences of intercept $b$; +- $\textit{cnt2}$ records the number of occurrences of the midpoint coordinates and slope $k$ of point pairs, with the key being the midpoint coordinates $p$ of the point pair and the value being another hash table that records the number of occurrences of slope $k$. + +For a point pair $(x_1, y_1)$ and $(x_2, y_2)$, we denote $dx = x_2 - x_1$ and $dy = y_2 - y_1$. If $dx = 0$, it means the two points are on the same vertical line, and we denote the slope $k = +\infty$ and the intercept $b = x_1$; otherwise, the slope $k = \frac{dy}{dx}$ and the intercept $b = \frac{y_1 \cdot dx - x_1 \cdot dy}{dx}$. The midpoint coordinates $p$ of the point pair can be expressed as $p = (x_1 + x_2 + 2000) \cdot 4000 + (y_1 + y_2 + 2000)$, where the offset is added to avoid negative numbers. + +Next, we iterate through all point pairs, calculate the corresponding slope $k$, intercept $b$, and midpoint coordinates $p$, and update the hash tables $\textit{cnt1}$ and $\textit{cnt2}$. + +Then, we iterate through the hash table $\textit{cnt1}$. For each slope $k$, we calculate the sum of all pairwise combinations of the occurrence counts of intercept $b$ and add it to the answer. Finally, we iterate through the hash table $\textit{cnt2}$. For each midpoint coordinate $p$, we calculate the sum of all pairwise combinations of the occurrence counts of slope $k$ and subtract it from the answer. + +The time complexity is $O(n^2)$ and the space complexity is $O(n^2)$, where $n$ is the number of points. #### Python3 ```python - +class Solution: + def countTrapezoids(self, points: List[List[int]]) -> int: + n = len(points) + + # cnt1: k -> (b -> count) + cnt1: dict[float, dict[float, int]] = defaultdict(lambda: defaultdict(int)) + # cnt2: p -> (k -> count) + cnt2: dict[int, dict[float, int]] = defaultdict(lambda: defaultdict(int)) + + for i in range(n): + x1, y1 = points[i] + for j in range(i): + x2, y2 = points[j] + dx, dy = x2 - x1, y2 - y1 + + if dx == 0: + k = 1e9 + b = x1 + else: + k = dy / dx + b = (y1 * dx - x1 * dy) / dx + + cnt1[k][b] += 1 + + p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000) + cnt2[p][k] += 1 + + ans = 0 + + for e in cnt1.values(): + s = 0 + for t in e.values(): + ans += s * t + s += t + + for e in cnt2.values(): + s = 0 + for t in e.values(): + ans -= s * t + s += t + + return ans ``` #### Java ```java - +class Solution { + public int countTrapezoids(int[][] points) { + int n = points.length; + Map> cnt1 = new HashMap<>(n * n); + Map> cnt2 = new HashMap<>(n * n); + + for (int i = 0; i < n; ++i) { + int x1 = points[i][0], y1 = points[i][1]; + for (int j = 0; j < i; ++j) { + int x2 = points[j][0], y2 = points[j][1]; + int dx = x2 - x1, dy = y2 - y1; + double k = dx == 0 ? Double.MAX_VALUE : 1.0 * dy / dx; + double b = dx == 0 ? x1 : 1.0 * (y1 * dx - x1 * dy) / dx; + if (k == -0.0) { + k = 0.0; + } + if (b == -0.0) { + b = 0.0; + } + cnt1.computeIfAbsent(k, _ -> new HashMap<>()).merge(b, 1, Integer::sum); + int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + cnt2.computeIfAbsent(p, _ -> new HashMap<>()).merge(k, 1, Integer::sum); + } + } + + int ans = 0; + for (var e : cnt1.values()) { + int s = 0; + for (int t : e.values()) { + ans += s * t; + s += t; + } + } + for (var e : cnt2.values()) { + int s = 0; + for (int t : e.values()) { + ans -= s * t; + s += t; + } + } + return ans; + } +} ``` #### C++ ```cpp - +class Solution { +public: + int countTrapezoids(vector>& points) { + int n = points.size(); + unordered_map> cnt1; + unordered_map> cnt2; + + cnt1.reserve(n * n); + cnt2.reserve(n * n); + + for (int i = 0; i < n; ++i) { + int x1 = points[i][0], y1 = points[i][1]; + for (int j = 0; j < i; ++j) { + int x2 = points[j][0], y2 = points[j][1]; + int dx = x2 - x1, dy = y2 - y1; + double k = (dx == 0 ? 1e9 : 1.0 * dy / dx); + double b = (dx == 0 ? x1 : 1.0 * (1LL * y1 * dx - 1LL * x1 * dy) / dx); + + cnt1[k][b] += 1; + int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + cnt2[p][k] += 1; + } + } + + int ans = 0; + for (auto& [_, e] : cnt1) { + int s = 0; + for (auto& [_, t] : e) { + ans += s * t; + s += t; + } + } + for (auto& [_, e] : cnt2) { + int s = 0; + for (auto& [_, t] : e) { + ans -= s * t; + s += t; + } + } + return ans; + } +}; ``` #### Go ```go +func countTrapezoids(points [][]int) int { + n := len(points) + cnt1 := make(map[float64]map[float64]int, n*n) + cnt2 := make(map[int]map[float64]int, n*n) + + for i := 0; i < n; i++ { + x1, y1 := points[i][0], points[i][1] + for j := 0; j < i; j++ { + x2, y2 := points[j][0], points[j][1] + dx, dy := x2-x1, y2-y1 + + var k, b float64 + if dx == 0 { + k = 1e9 + b = float64(x1) + } else { + k = float64(dy) / float64(dx) + b = float64(int64(y1)*int64(dx)-int64(x1)*int64(dy)) / float64(dx) + } + + if cnt1[k] == nil { + cnt1[k] = make(map[float64]int) + } + cnt1[k][b]++ + + p := (x1+x2+2000)*4000 + (y1 + y2 + 2000) + if cnt2[p] == nil { + cnt2[p] = make(map[float64]int) + } + cnt2[p][k]++ + } + } + + ans := 0 + for _, e := range cnt1 { + s := 0 + for _, t := range e { + ans += s * t + s += t + } + } + for _, e := range cnt2 { + s := 0 + for _, t := range e { + ans -= s * t + s += t + } + } + return ans +} +``` +#### TypeScript + +```ts +function countTrapezoids(points: number[][]): number { + const n = points.length; + + const cnt1: Map> = new Map(); + const cnt2: Map> = new Map(); + + for (let i = 0; i < n; i++) { + const [x1, y1] = points[i]; + for (let j = 0; j < i; j++) { + const [x2, y2] = points[j]; + const [dx, dy] = [x2 - x1, y2 - y1]; + + const k = dx === 0 ? 1e9 : dy / dx; + const b = dx === 0 ? x1 : (y1 * dx - x1 * dy) / dx; + + if (!cnt1.has(k)) { + cnt1.set(k, new Map()); + } + const mapB = cnt1.get(k)!; + mapB.set(b, (mapB.get(b) || 0) + 1); + + const p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + + if (!cnt2.has(p)) { + cnt2.set(p, new Map()); + } + const mapK = cnt2.get(p)!; + mapK.set(k, (mapK.get(k) || 0) + 1); + } + } + + let ans = 0; + for (const e of cnt1.values()) { + let s = 0; + for (const t of e.values()) { + ans += s * t; + s += t; + } + } + for (const e of cnt2.values()) { + let s = 0; + for (const t of e.values()) { + ans -= s * t; + s += t; + } + } + + return ans; +} ``` diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.cpp b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.cpp new file mode 100644 index 0000000000000..968d267391ed9 --- /dev/null +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.cpp @@ -0,0 +1,42 @@ +class Solution { +public: + int countTrapezoids(vector>& points) { + int n = points.size(); + unordered_map> cnt1; + unordered_map> cnt2; + + cnt1.reserve(n * n); + cnt2.reserve(n * n); + + for (int i = 0; i < n; ++i) { + int x1 = points[i][0], y1 = points[i][1]; + for (int j = 0; j < i; ++j) { + int x2 = points[j][0], y2 = points[j][1]; + int dx = x2 - x1, dy = y2 - y1; + double k = (dx == 0 ? 1e9 : 1.0 * dy / dx); + double b = (dx == 0 ? x1 : 1.0 * (1LL * y1 * dx - 1LL * x1 * dy) / dx); + + cnt1[k][b] += 1; + int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + cnt2[p][k] += 1; + } + } + + int ans = 0; + for (auto& [_, e] : cnt1) { + int s = 0; + for (auto& [_, t] : e) { + ans += s * t; + s += t; + } + } + for (auto& [_, e] : cnt2) { + int s = 0; + for (auto& [_, t] : e) { + ans -= s * t; + s += t; + } + } + return ans; + } +}; diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.go b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.go new file mode 100644 index 0000000000000..91e18834a8b33 --- /dev/null +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.go @@ -0,0 +1,50 @@ +func countTrapezoids(points [][]int) int { + n := len(points) + cnt1 := make(map[float64]map[float64]int, n*n) + cnt2 := make(map[int]map[float64]int, n*n) + + for i := 0; i < n; i++ { + x1, y1 := points[i][0], points[i][1] + for j := 0; j < i; j++ { + x2, y2 := points[j][0], points[j][1] + dx, dy := x2-x1, y2-y1 + + var k, b float64 + if dx == 0 { + k = 1e9 + b = float64(x1) + } else { + k = float64(dy) / float64(dx) + b = float64(int64(y1)*int64(dx)-int64(x1)*int64(dy)) / float64(dx) + } + + if cnt1[k] == nil { + cnt1[k] = make(map[float64]int) + } + cnt1[k][b]++ + + p := (x1+x2+2000)*4000 + (y1 + y2 + 2000) + if cnt2[p] == nil { + cnt2[p] = make(map[float64]int) + } + cnt2[p][k]++ + } + } + + ans := 0 + for _, e := range cnt1 { + s := 0 + for _, t := range e { + ans += s * t + s += t + } + } + for _, e := range cnt2 { + s := 0 + for _, t := range e { + ans -= s * t + s += t + } + } + return ans +} diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.java b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.java new file mode 100644 index 0000000000000..4530e7bc21e84 --- /dev/null +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.java @@ -0,0 +1,43 @@ +class Solution { + public int countTrapezoids(int[][] points) { + int n = points.length; + Map> cnt1 = new HashMap<>(n * n); + Map> cnt2 = new HashMap<>(n * n); + + for (int i = 0; i < n; ++i) { + int x1 = points[i][0], y1 = points[i][1]; + for (int j = 0; j < i; ++j) { + int x2 = points[j][0], y2 = points[j][1]; + int dx = x2 - x1, dy = y2 - y1; + double k = dx == 0 ? Double.MAX_VALUE : 1.0 * dy / dx; + double b = dx == 0 ? x1 : 1.0 * (y1 * dx - x1 * dy) / dx; + if (k == -0.0) { + k = 0.0; + } + if (b == -0.0) { + b = 0.0; + } + cnt1.computeIfAbsent(k, _ -> new HashMap<>()).merge(b, 1, Integer::sum); + int p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + cnt2.computeIfAbsent(p, _ -> new HashMap<>()).merge(k, 1, Integer::sum); + } + } + + int ans = 0; + for (var e : cnt1.values()) { + int s = 0; + for (int t : e.values()) { + ans += s * t; + s += t; + } + } + for (var e : cnt2.values()) { + int s = 0; + for (int t : e.values()) { + ans -= s * t; + s += t; + } + } + return ans; + } +} diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.py b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.py new file mode 100644 index 0000000000000..47173e9d8e263 --- /dev/null +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.py @@ -0,0 +1,42 @@ +class Solution: + def countTrapezoids(self, points: List[List[int]]) -> int: + n = len(points) + + # cnt1: k -> (b -> count) + cnt1: dict[float, dict[float, int]] = defaultdict(lambda: defaultdict(int)) + # cnt2: p -> (k -> count) + cnt2: dict[int, dict[float, int]] = defaultdict(lambda: defaultdict(int)) + + for i in range(n): + x1, y1 = points[i] + for j in range(i): + x2, y2 = points[j] + dx, dy = x2 - x1, y2 - y1 + + if dx == 0: + k = 1e9 + b = x1 + else: + k = dy / dx + b = (y1 * dx - x1 * dy) / dx + + cnt1[k][b] += 1 + + p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000) + cnt2[p][k] += 1 + + ans = 0 + + for e in cnt1.values(): + s = 0 + for t in e.values(): + ans += s * t + s += t + + for e in cnt2.values(): + s = 0 + for t in e.values(): + ans -= s * t + s += t + + return ans diff --git a/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.ts b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.ts new file mode 100644 index 0000000000000..eecf7ba2707d0 --- /dev/null +++ b/solution/3600-3699/3625.Count Number of Trapezoids II/Solution.ts @@ -0,0 +1,49 @@ +function countTrapezoids(points: number[][]): number { + const n = points.length; + + const cnt1: Map> = new Map(); + const cnt2: Map> = new Map(); + + for (let i = 0; i < n; i++) { + const [x1, y1] = points[i]; + for (let j = 0; j < i; j++) { + const [x2, y2] = points[j]; + const [dx, dy] = [x2 - x1, y2 - y1]; + + const k = dx === 0 ? 1e9 : dy / dx; + const b = dx === 0 ? x1 : (y1 * dx - x1 * dy) / dx; + + if (!cnt1.has(k)) { + cnt1.set(k, new Map()); + } + const mapB = cnt1.get(k)!; + mapB.set(b, (mapB.get(b) || 0) + 1); + + const p = (x1 + x2 + 2000) * 4000 + (y1 + y2 + 2000); + + if (!cnt2.has(p)) { + cnt2.set(p, new Map()); + } + const mapK = cnt2.get(p)!; + mapK.set(k, (mapK.get(k) || 0) + 1); + } + } + + let ans = 0; + for (const e of cnt1.values()) { + let s = 0; + for (const t of e.values()) { + ans += s * t; + s += t; + } + } + for (const e of cnt2.values()) { + let s = 0; + for (const t of e.values()) { + ans -= s * t; + s += t; + } + } + + return ans; +}