【ZOJ1041】Transmitters【叉积】

版权声明:若希望转载,在评论里直接说明即可,谢谢! https://blog.csdn.net/SSL_ZYC/article/details/85702926

题目大意:

题目链接:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=41
https://www.luogu.org/problemnew/show/SP898
以雷达心为圆心的半圆形雷达覆盖范围有多个点,雷达可旋转,求最多覆盖数(含在边界的)。


思路:

叉积基础题。
首先很明显的可以先把不在雷达范围之内的点忽略掉。可以在读入时求出该点到雷达的距离,如果在半径之内才加入点集。
然后考虑对于每一个点 i i ,如果以雷达位置和点 i i 所在直线为半圆(雷达扫描面积)的直径所在直线,那么只有两种可能。
在这里插入图片描述
而其他的任意一点 j j ,要么会在黄色区域,要么会在绿色区域,要么就是在该直线上(即两个区域都属于)。
如果属于黄色区域,那么在以雷达(红色)为原点的平面直角坐标系中, i i j j 的叉积就会 0 \geq 0 ,如果在绿色区域叉积就会 0 \leq 0 。(如果在直线上,叉积 = 0 =0 ,两边都会计算)。
然后取个 m a x max 就可以了。


代码:

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;

const int N=1010;
int n,m,ans,s1,s2;
double x,y,xx,yy,r;

struct node
{
	double x,y;
}a[N];

double cal(double x1,double y1,double x2,double y2)  //勾股求距离
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main()
{
	while (scanf("%lf%lf%lf",&x,&y,&r)==3&&r>=0.0)
	{
		n=0;
		scanf("%d",&m);
		for (int i=1;i<=m;i++)
		{
			scanf("%lf%lf",&xx,&yy);
			if (cal(x,y,xx,yy)<=r)  //在雷达范围内
			{
				a[++n].x=xx-x;
				a[n].y=yy-y;  //切记直接减去雷达所在位置。因为是以雷达为原点的平面直角坐标系。
			}
		}
		ans=0;
		for (int i=1;i<=n;i++)
		{
			s1=s2=0;
			for (int j=1;j<=n;j++)
			{
				if (a[i].x*a[j].y-a[j].x*a[i].y>=0.0) s1++;
				if (a[i].x*a[j].y-a[j].x*a[i].y<=0.0) s2++;  //叉积
			}
			ans=max(ans,max(s1,s2));
		}
		printf("%d\n",ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_ZYC/article/details/85702926