1. 程式人生 > 實用技巧 >1610. 可見點的最大數目

1610. 可見點的最大數目

給你一個點陣列 points 和一個表示角度的整數 angle ,你的位置是 location ,其中 location = [posx, posy] 且 points[i] = [xi, yi] 都表示 X-Y 平面上的整數座標。

最開始,你面向東方進行觀測。你 不能 進行移動改變位置,但可以通過 自轉 調整觀測角度。換句話說,posx 和 posy 不能改變。你的視野範圍的角度用 angle 表示, 這決定了你觀測任意方向時可以多寬。設 d 為你逆時針自轉旋轉的度數,那麼你的視野就是角度範圍 [d - angle/2, d + angle/2] 所指示的那片區域。

對於每個點,如果由該點、你的位置以及從你的位置直接向東的方向形成的角度 位於你的視野中 ,那麼你就可以看到它。

同一個座標上可以有多個點。你所在的位置也可能存在一些點,但不管你的怎麼旋轉,總是可以看到這些點。同時,點不會阻礙你看到其他點。

返回你能看到的點的最大數目。

示例 1:

輸入:points = [[2,1],[2,2],[3,3]], angle = 90, location = [1,1]
輸出:3
解釋:陰影區域代表你的視野。在你的視野中,所有的點都清晰可見,儘管 [2,2] 和 [3,3]在同一條直線上,你仍然可以看到 [3,3] 。
示例 2:

輸入:points = [[2,1],[2,2],[3,4],[1,1]], angle = 90, location = [1,1]
輸出:4
解釋:在你的視野中,所有的點都清晰可見,包括你所在位置的那個點。
示例 3:

輸入:points = [[1,0],[2,1]], angle = 13, location = [1,1]
輸出:1
解釋:如圖所示,你只能看到兩點之一。

提示:

1 <= points.length <= 105
points[i].length == 2
location.length == 2
0 <= angle < 360
0 <= posx, posy, xi, yi <= 109

const double eps = 1e-8;
class Solution {
public:
    int visiblePoints(vector<vector<int
>>& points, int angle, vector<int>& location) { int x = location[0]; int y = location[1]; int same = 0; vector<double> v; for (auto p : points) { int px = p[0], py = p[1]; if (px == x && py == y) same++; else v.emplace_back(atan2(px - x, py - y) * 180 / M_PI); } sort(v.begin(), v.end()); int sz = v.size(); for (int i = 0; i < sz; i++) v.emplace_back(v[i] + 360); int r = 0, mx = 0; for (int l = 0; l < sz; l++) { while (r + 1 < v.size() && v[r + 1] - v[l] <= (double)angle + eps) r++; mx = max(mx, r - l + 1); } return mx + same; } };