From 4b5b5b4a1a706714706bdf61dbdb29dcde73a6f1 Mon Sep 17 00:00:00 2001 From: Eat-Swap Date: Thu, 9 Jun 2022 22:25:19 +0800 Subject: [PATCH] add: 220609-CN [cpp] --- cpp/2206/220609-CN.cpp | 77 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 cpp/2206/220609-CN.cpp diff --git a/cpp/2206/220609-CN.cpp b/cpp/2206/220609-CN.cpp new file mode 100644 index 0000000..a2589de --- /dev/null +++ b/cpp/2206/220609-CN.cpp @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +/** + * 497. Random Point in Non-overlapping Rectangles + * + * You are given an array of non-overlapping axis-aligned rectangles rects where rects[i] = [ai, bi, xi, yi] indicates that (ai, bi) is the bottom-left corner point of the ith rectangle and (xi, yi) is the top-right corner point of the ith rectangle. Design an algorithm to pick a random integer point inside the space covered by one of the given rectangles. A point on the perimeter of a rectangle is included in the space covered by the rectangle. + * Any integer point inside the space covered by one of the given rectangles should be equally likely to be returned. + * Note that an integer point is a point that has integer coordinates. + * Implement the Solution class: + * Solution(int[][] rects) Initializes the object with the given rectangles rects. + * int[] pick() Returns a random integer point [u, v] inside the space covered by one of the given rectangles. + */ + +class Solution { +private: + std::vector> r; + + std::vector pSum; + + int total; + + std::mt19937 rnd; + + int randIntN(int n) { + return rnd() % n; + } + +public: + explicit Solution(std::vector> rects) { + r = std::move(rects); + rnd = std::mt19937(std::time(nullptr)); + pSum = std::vector(r.size()); + for (int i = 1; i < r.size(); ++i) { + const auto& x = r[i - 1]; + pSum[i] = pSum[i - 1] + (x[2] - x[0] + 1) * (x[3] - x[1] + 1); + } + total = pSum.back() + (r.back()[2] - r.back()[0] + 1) * (r.back()[3] - r.back()[1] + 1); + } + + std::vector pick() { + int pno = randIntN(total); + int rno = std::upper_bound(pSum.begin(), pSum.end(), pno) - pSum.begin() - 1; + const auto& t = r[rno]; + int x1 = t[0], + y1 = t[1], + x2 = t[2], + y2 = t[3], + rn = pno - pSum[rno]; + return {x1 + rn / (y2 - y1 + 1), y1 + rn % (y2 - y1 + 1)}; + } +}; + +int main() { + std::vector> rect {{82918473,-57180867,82918476,-57180863},{83793579,18088559,83793580,18088560},{66574245,26243152,66574246,26243153},{72983930,11921716,72983934,11921720}}; + Solution s(rect); + + for (int i = 0; ; ++i) { + auto x = s.pick(); + bool OK = false; + for (const auto& r : rect) { + if (x[0] >= r[0] && x[0] <= r[2] && x[1] >= r[1] && x[1] <= r[3]) { + OK = true; + break; + } + } + if (!OK) { + std::printf("0x%08X: Failed when returning {%d, %d}\n", i, x[0], x[1]); + } else { + // std::printf("0x%08X: OK\n", i); + } + } + + return 0; +}