解题思路
先看题,视野无限延伸,所以肯定不会去想求视野面积然后用直角坐标系算相对位置。
视野两边无限延伸让人想到什么?没错,就是角度,想到角度就容易想到另外一个坐标系:极坐标系。
先看下面的图:
三角形AOB,AB是y BO是x,那么求∠AOB怎么求呢?很简单,
tanθ=y/x;
θ = arctan y/x
转化为代码就是:atan2(y,x);
所以,我们可以把人的位置看作极坐标的原点O,那么就需要算出每个点先对于O的极角θ
所以θ = arctan dy/dx(其中dy = yi - y0, dx = xi - x0)
转化为代码就是: double cur = atan2(p[1] - location[1], p[0] - location[0]);
然后对这些角度进行排序(排序的作用见后面)
直接代入极坐标来算的话,就需要额外考虑θ为负数的情况,这时候我们直接+2π,角度实际上没有改变,但是避免了讨论负数弧度的问题。
注意!!atan2函数返回的是角度,题目angle给的是弧度(角度的整数)需要转化一下;
弧度转角度的公式:
degree = 180/π×弧度
此时问题就转化为:
设O为原点,设polar[i]为A,设∠AOC 为 degree(就是一个边界视角落在A上)
有多少点会落在∠AOC里
也就是说:
设这个点为B,有多少个B可以满足∠AOB小于∠AOC
因为上面对这个进行排序了,所以我们通过while循环就可以算出满足条件B的总数,提高了效率。
(滑动窗口,窗口大小为degree)
然后提取所有点作为一个边界的情况下最大落点数:cnt
由于题意描述与 location 重合的点在任意角度都能看到,所以最开始特殊处理的这些数量在返回的时候要记得加上。
代码
class Solution {
public:
int visiblePoints(vector<vector<int>>& points