1. 程式人生 > >Leetcode:478. 在圓內隨機生成點

Leetcode:478. 在圓內隨機生成點

給定圓的半徑和圓心的 x、y 座標,寫一個在圓中產生均勻隨機點的函式 randPoint 。

說明:

  1. 輸入值和輸出值都將是浮點數
  2. 圓的半徑和圓心的 x、y 座標將作為引數傳遞給類的建構函式。
  3. 圓周上的點也認為是在圓中。
  4. randPoint 返回一個包含隨機點的x座標和y座標的大小為2的陣列。

示例 1:

輸入: 
["Solution","randPoint","randPoint","randPoint"]
[[1,0,0],[],[],[]]
輸出: [null,[-0.72939,-0.65505],[-0.78502,-0.28626],[-0.83119,-0.19803]]

示例 2:

輸入: 
["Solution","randPoint","randPoint","randPoint"]
[[10,5,-7.5],[],[],[]]
輸出: [null,[11.52438,-8.33273],[2.46992,-16.21705],[11.13430,-12.42337]]

輸入語法說明:

輸入是兩個列表:呼叫成員函式名和呼叫的引數。Solution 的建構函式有三個引數,圓的半徑、圓心的 x 座標、圓心的 y 座標。randPoint 沒有引數。輸入引數是一個列表,即使引數為空,也會輸入一個 [] 空列表。

解題思路:

蒙特卡洛,隨機模擬。產生2個範圍[-r,r]之間的隨機數dx,dy,理論上(x+dx,y+dy)在{{x-r,y-r},{x+r,y+r}}矩形(左下角,右上角)範圍內。新增判斷(x+dx,y+dy)距離圓心的距離小於r即可。個人不推薦極座標法

,原因是要呼叫sin,cos等函式,效率較低。也不多BB了,124ms有史最快,在這之前136ms已經能擊敗100%了。

C++程式碼

class Solution {
public:
    Solution(double radius, double x_center, double y_center) {
        r = radius; x = x_center; y = y_center;
    }
    vector<double> randPoint() {
        double dx = r*(rand() % 20001 - 10000)*0.0001;
        double dy = r*(rand() % 20001 - 10000)*0.0001;
        while (dx*dx + dy*dy > r*r) {
            dx = r*(rand() % 20001 - 10000)*0.0001;
            dy = r*(rand() % 20001 - 10000)*0.0001;
        }
        return{ x + dx,y + dy };
    }
    double r, x, y;
};

static int x = []() {
     std::ios::sync_with_stdio(false);
     cin.tie(NULL);
     return 0;
}();