diff --git a/cpp/2305/LC230520.cpp b/cpp/2305/LC230520.cpp new file mode 100644 index 0000000..997579b --- /dev/null +++ b/cpp/2305/LC230520.cpp @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +/** + * 399. Evaluate Division + * You are given an array of variable pairs equations and an array of real numbers values, where equations[i] = [Ai, Bi] and values[i] represent the equation Ai / Bi = values[i]. Each Ai or Bi is a string that represents a single variable. + * You are also given some queries, where queries[j] = [Cj, Dj] represents the jth query where you must find the answer for Cj / Dj = ?. + * Return the answers to all queries. If a single answer cannot be determined, return -1.0. + */ + +class LC230520 { +public: + template + using V = std::vector; + using VD = V; + using CVVS = const V>; + + static VD calcEquation(CVVS&, const VD&, CVVS&) noexcept; +}; + +std::vector LC230520::calcEquation(CVVS& equations, const VD& values, CVVS& queries) noexcept { + const int n = equations.size(); + std::unordered_map id_map; + std::unordered_map> directed_map; + int cnt = 0; + for (int i = 0; i < n; ++i) { + for (int j = 0; j < 2; ++j) + if (!id_map.count(equations[i][j])) + id_map[equations[i][j]] = cnt++; + directed_map[id_map[equations[i][0]]][id_map[equations[i][1]]] = values[i]; + directed_map[id_map[equations[i][1]]][id_map[equations[i][0]]] = 1.0 / values[i]; + } + VD ret; + for (auto&& t : queries) { + if (!(id_map.count(t[0]) && id_map.count(t[1]))) { + ret.push_back(-1.0); + continue; + } + int numerator = id_map[t[0]], denominator = id_map[t[1]]; + if (numerator == denominator) { + ret.push_back(1.0); + continue; + } + int vis = 1 << numerator; + bool found = false; + std::queue> q; + q.emplace(numerator, 1.0); + while (!q.empty()) { + auto [c, cr] = q.front(); + for (auto [nc, ncr] : directed_map[c]) { + if (vis & (1 << nc)) + continue; + vis |= 1 << nc; + if (nc == denominator) { + found = true; + ret.push_back(cr * ncr); + break; + } + q.emplace(nc, cr * ncr); + } + if (found) + break; + } + if (!found) + ret.push_back(-1); + } + return ret; +} diff --git a/cpp/2305/defs.h b/cpp/2305/defs.h index 8ca2142..d683252 100644 --- a/cpp/2305/defs.h +++ b/cpp/2305/defs.h @@ -134,4 +134,14 @@ public: static int countGoodStrings(int, int, int, int) noexcept; }; +class LC230520 { +public: + template + using V = std::vector; + using VD = V; + using CVVS = const V>; + + static VD calcEquation(CVVS&, const VD&, CVVS&) noexcept; +}; + #endif //LEETCODE_CPP_DEFS_H diff --git a/cpp/2305/main.cpp b/cpp/2305/main.cpp index 08b49b3..cdddd58 100644 --- a/cpp/2305/main.cpp +++ b/cpp/2305/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -13,7 +14,44 @@ std::ostream& operator<<(std::ostream& os, const std::vector& x) noexcept { return os; } +int* partition(int* L, int* R) { + int pivot = R - L; + std::swap(L[rand() % pivot], *R); + int pivot_index = 0; + for (int i = 0; i < pivot; ++i) + if (L[i] < *R) + std::swap(L[i], L[pivot_index++]); + std::swap(*R, L[pivot_index]); + return pivot_index + L; +} + +void quick_sort(int* L, int* R) { + if (L >= R) + return; + if (R - L == 1) { + if (*L > *R) + std::swap(*L, *R); + return; + } + int* pivot = partition(L, R); + quick_sort(L, pivot - 1); + quick_sort(pivot + 1, R); +} + +void heapify(int* L, int* R) { + int len = R - L + 1; + int* rs = L - 1; + for (int i = len; i; --i) { + if (rs[i] > rs[i >> 1]) + std::swap(rs[i], rs[i >> 1]); + } +} + int main() { - std::cout << LC230513::countGoodStrings(2,3,1,2); + LC230520::calcEquation( + {{"a", "b"}, {"b", "c"}}, + {2.0, 3.0}, + {{"a", "c"}, {"b", "a"}} + ); return 0; }