由于烽火台只能向左边瞭望,所以本题就是求图中的所有“凸起来的点”,那么哪些点是“凸起来的点”?

如下图所示,点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");
}