• 【ZOJ1041】Transmitters【叉积】


    题目大意:

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


    思路:

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


    代码:

    #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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    LeetCode208 实现 Trie (前缀树)
    LeetCode289 生命游戏(模拟)
    LeetCode560 和为 K 的子数组
    LeetCode673 最长递增子序列的个数
    LeetCode31 下一个排列
    LeetCode926 将字符串翻转到单调递增
    LeetCode135 分发糖果
    LeetCode810 黑板异或游戏
    npm发布和修改详细教程
    不同的子序列问题I
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998418.html
Copyright © 2020-2023  润新知