由于烽火台只能向左边瞭望,所以本题就是求图中的所有“凸起来的点”,那么哪些点是“凸起来的点”?
如下图所示,点C就是凸点。
这个图好像和凸包有点像,那么是不是“凸起来的点”是不是凸包上的点呢,显然不是,比如下图
那么反过来,凸包上的点一定是“凸起来的点”吗?是的。并且这些点都曾经是凸包里面的点!
首先假设在加入了某个点后形成了一个凸包,那么除了这个点的其他点都是凸点。(请大家仔细思考)
然后每次加入一个点的时候,标记 在加入这个点前 的最后一个点的编号就可以了。
code:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool book[100005];
struct point
{
int id;
ll x;
ll y;
point operator-(point other)
{
return point{ 0,x - other.x,y - other.y };
}
double operator^(point b)
{
return 1.0 *x * b.y - 1.0*b.x*y;
}
}in[100005], que[100005];
bool judge(point a, point b, point c)
{
point ab = b - a;
point ac = c - a;
return (ab ^ ac) <= 0;
}
int main()
{
int n, ans = 0;
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
in[i].id = i + 1;
scanf("%lld%lld", &in[i].x, &in[i].y);
}
int flag = 0;
for (int i = 0; i < n; i++)
{
while (flag > 1 && judge(que[flag - 2], que[flag - 1], in[i]))
flag--;
if (flag > 0)
book[que[flag - 1].id] = true;
que[flag++] = in[i];
}
flag = 0;
for (int i = 2; i <= n; i++)
if (book[i] == true)
flag++;
printf("%d", flag);
system("pause");
}