zoukankan      html  css  js  c++  java
  • 半平面交O(n)判断

    先放在这里,本来是要写CF549E的但是正解不是这个

    O(n)判断半平面交

    判断面积>=0

    随机打乱顺序,依次加进去同时维护一个在半平面交内且y最小的点

    如果点不在新加的半平面内就对和之前的半平面暴力求交点,在剩下的区间上取y最小的

    交出来区间为空就不存在

    看起来很玄,考虑时间复杂度

    对于当前加的第i条边,需要修改的情况当且仅当第i条边是1~i条边组成的半平面中最下面的两条之一,由于随机打乱了所以期望是2/i

    那么时间就是(sum frac{2}{i}*O(i)+(1-frac{2}{i})*O(1)=O(n))

    有可能当前的半平面没有封底,所以加一条y=-inf即可,实际可以不用加

    求交的时候用点积判断(模长*投影长)

    代码并没有调出来,也许以后再说

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define abs(x) ((x)>0?(x):-(x))
    #define E 0.000000001
    #define ll long long
    #define file
    using namespace std;
    
    struct point {double x,y;} a[10001],b[10001],p1,p2,P;
    struct xl {double X1,Y1,X2,Y2;} c,c2,s1,s2;
    int n,m,i,j,k,l,randomseed;
    
    double cj(xl a,xl b) {return (b.X2-b.X1)*(a.Y2-a.Y1)-(a.X2-a.X1)*(b.Y2-b.Y1);};
    double dj(xl a,xl b) {return (a.X2-a.X1)*(b.X2-b.X1)+(a.Y2-a.Y1)*(b.Y2-b.Y1);};
    point jd(xl a,xl b)
    {
    	double s1=cj({a.X1,a.Y1,b.X2,b.Y2},a),s2=cj(a,{a.X1,a.Y1,b.X1,b.Y1});
    	if (abs(s1+s2)<E) return{-114514,-1919810};
    	double s=s2/(s1+s2);
    	
    	return {b.X1+(b.X2-b.X1)*s,b.Y1+(b.Y2-b.Y1)*s};
    }
    
    void work(bool type)
    {
    	double x=0,y=-114514,m1,m2,s;
    	bool bz1=1,bz2=1,bz3=1;
    	int i,j,k,l;
    	
    	random_shuffle(a+1,a+n+1);
    	random_shuffle(b+1,b+m+1);
    	fo(i,1,n)
    	{
    		fo(j,1,m)
    		if (a[i].x==b[j].x && a[i].y==b[j].y) {printf("NO
    "); exit(0);}
    		else
    		{
    			c={(a[i].x+b[j].x)/2.0,(a[i].y+b[j].y)/2.0};
    			if (!type) c.X2=c.X1-(a[i].y-b[j].y),c.Y2=c.Y1+(a[i].x-b[j].x);
    			else c.X2=c.X1+(a[i].y-b[j].y),c.Y2=c.Y1-(a[i].x-b[j].x);
    			
    			if (cj({c.X1,c.Y1,x,y},c)>E)
    			{
    				p1={c.X1-(c.X2-c.X1)*20000,c.Y1-(c.Y2-c.Y1)*20000};m1=-9223372036854775807ll;
    				p2={c.X1+(c.X2-c.X1)*20000,c.Y1+(c.Y2-c.Y1)*20000};m2=9223372036854775807ll;
    				
    				fo(k,1,i)
    				{
    					fo(l,1,m)
    					if (k==i && l==j) break;
    					else
    					{
    						c2={(a[k].x+b[l].x)/2.0,(a[k].y+b[l].y)/2.0};
    						if (!type) c2.X2=c2.X1-(a[k].y-b[l].y),c2.Y2=c2.Y1+(a[k].x-b[l].x);
    						else c2.X2=c2.X1+(a[k].y-b[l].y),c2.Y2=c2.Y1-(a[k].x-b[l].x);
    						
    						P=jd(c,c2);
    						if (P.y==-1919810)
    						{
    							if (cj({c.X1,c.Y1,c2.X1,c2.Y1},c)>E && cj({c2.X1,c2.Y1,c.X1,c.Y1},c2)>E)
    							return;
    							else
    							continue;
    						}
    						
    						if (cj(c,{c.X1,c.Y1,c2.X1,c2.Y1})<cj(c,{c.X1,c.Y1,c2.X2,c2.Y2}))
    						{s=dj(c,{c.X1,c.Y1,P.x,P.y});if (s<m2) m2=s,p2=P;}
    						else
    						{s=dj(c,{c.X1,c.Y1,P.x,P.y});if (s>m1) m1=s,p1=P;}
    						if (m1>m2) return;
    					}
    				}
    				if (p1.y<p2.y) x=p1.x,y=p1.y; else x=p2.x,y=p2.y;
    			}
    		}
    	}
    	fo(i,1,n)
    	{
    		fo(j,1,m)
    		{
    			c={(a[i].x+b[j].x)/2.0,(a[i].y+b[j].y)/2.0};
    			if (!type) c.X2=c.X1-(a[i].y-b[j].y),c.Y2=c.Y1+(a[i].x-b[j].x);
    			else c.X2=c.X1+(a[i].y-b[j].y),c.Y2=c.Y1-(a[i].x-b[j].x);
    			
    			s=cj(c,{c.X1,c.Y1,x+0.000001,y+0.000001}),bz1&=s>E;
    			s=cj(c,{c.X1,c.Y1,x-0.000001,y+0.000001}),bz2&=s>E;
    			s=cj(c,{c.X1,c.Y1,x,y+0.000001}),bz3&=s>E;
    			if (!bz1 && !bz2 && !bz3) return;
    		}
    	}
    	printf("YES
    ");exit(0);
    }
    
    int main()
    {
    	randomseed=time(NULL);
    	srand(randomseed);
    	freopen("cf549E.in","r",stdin);
    	#ifdef file
    	freopen("b.out","w",stdout);
    	#endif
    //	#ifdef file
    //	freopen("cf549E.in","r",stdin);
    //	#endif
    	
    	scanf("%d%d",&n,&m);
    	fo(i,1,n) scanf("%lf%lf",&a[i].x,&a[i].y);
    	fo(i,1,m) scanf("%lf%lf",&b[i].x,&b[i].y);
    	
    	work(0);work(1);
    	printf("NO
    ");
    	
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

    参考资料

    https://wenku.baidu.com/view/9097ccd549649b6648d74712.html

    https://wenku.baidu.com/view/a836ff44ad02de80d4d84095.html

  • 相关阅读:
    springboot启动时不加载数据库
    ElasticSearch常用的查询操作
    Windows10 搭建ElasticSearch集群服务
    windows10安装ElasticSearch7.5遇到两个警告解决方法
    MybatisPlus自动生成代码配置
    初识RabbitMQ ------基本概念
    深拷贝与浅拷贝的区别
    Java8中 LocalDateTime与Date互相转换
    Spring中常用的工具类StringUtils、DateUtils、CollectionUtils等
    SpringBoot定时任务 @Scheduled cron 表达式说明
  • 原文地址:https://www.cnblogs.com/gmh77/p/12916223.html
Copyright © 2011-2022 走看看