[sslOJ 1232] [ZOJ 1041] 雷达覆盖(normal)


题面

sslOJ \(LINK\)
ZOJ \(LINK\)

解析

可以考虑通过计算,算出雷达与其他的点的距离,超过半径的点判为不合法的点(因为不论怎样都无法被扫描到,贡献恒为零)。然后枚举每一个合法的点,以雷达和这个点的连线的延长线为标准,判断是属于哪个半圆的点(如果在直径上,那就是属于两个半圆的点),然后再取所有半圆的最大值

Code

#include 
#include 
using namespace std;
 
double hd;
int tr, ans; 
int rx, ry, n;
int x[1005], y[1005];

double dis (int x1, int x2, int y1, int y2)
{
	return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
}

int main ()
{
	while (scanf ("%d%d%lf%d", &rx, &ry, &hd, &n) == 4)
	{
		ans = tr = 0;
		for (int i = 1; i <= n; ++ i)
		{
			int L_x, L_y;
			scanf ("%d%d", &L_x, &L_y);
			if (dis (L_x, rx, L_y, ry) > hd * hd) continue;
			x[++ tr] = L_x; y[tr] = L_y; 
		}
		for (int i = 1;i <= tr; ++ i)
		{
			int l = 0, r =0;
			for (int j = 1; j <= tr; ++ j)
			{
				int m = (x[i] - rx) * (y[j] - ry) - (y[i] - ry) * (x[j] - rx);
				if (m >= 0) ++ r;
				if (m <= 0) ++ l;
			}
			ans = max (ans, max (l, r));
		}
		printf ("%d\n", ans);
	}
	return 0;
}