• 【UOJ#242】【UR#16】破坏蛋糕(计算几何)


    【UOJ#242】【UR#16】破坏蛋糕(计算几何)

    题面

    UOJ

    题解

    为了方便,我们假定最后一条直线是从上往下穿过来的,比如说把它当成坐标系的(y)轴。
    于是我们可以处理出所有交点,然后把它们从上往下排序。
    相邻的两个点就构成了一个相交的平面(可以认为正无穷和负无穷位置还有一个点)
    那么,这个区间是有限的,当且仅当过这个两点的直线在左侧都还能找到一个交点,在右侧也还能找到一个交点。
    于是考虑怎么找交点,两侧基本等价,所以拆开考虑,比如考虑右侧。
    我们从上往下依次扫每一个过每一个交点的直线,如果在这条直线上方存在一条直线,满足斜率小于这条直线,那么就会和这条直线有交,于是我们可以维护一些斜率的单调栈,每次二分一段区间,找到最靠上的那个,那么这一段区间内的所有点的右侧都是封闭的,差分一下就可以知道所有点的情况;左侧的情况是类似的。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define ll long long
    #define MAX 100100
    const double Pi=acos(-1),eps=1e-7;
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    struct Node{double x,y;}G[MAX];
    double Len(Node a){return sqrt(a.x*a.x+a.y*a.y);}
    Node operator+(Node a,Node b){return (Node){a.x+b.x,a.y+b.y};}
    Node operator-(Node a,Node b){return (Node){a.x-b.x,a.y-b.y};}
    Node operator*(Node a,double b){return (Node){a.x*b,a.y*b};}
    double Cross(Node a,Node b){return a.x*b.y-a.y*b.x;}
    struct Line{Node p,v;}L[MAX],pL[MAX];
    Node Intersection(Line a,Line b)
    {
    	Node c=b.p-a.p;
    	double t=Cross(b.v,c)/Cross(b.v,a.v);
    	return a.p+a.v*t;
    }
    bool Parallel(Line a,Line b){return fabs(Cross(a.v,b.v))<1e-9;}
    Node Turn(Node a,double alp){return (Node){a.x*cos(alp)-a.y*sin(alp),a.x*sin(alp)+a.y*cos(alp)};}
    int n,id[MAX];double K[MAX];
    bool cmpid(int a,int b){return G[a].y>G[b].y;}
    int St[MAX],cl[MAX],cr[MAX];
    double ang[MAX];
    int main()
    {
    	n=read();
    	for(int i=1;i<=n+1;++i)
    	{
    		double x1=read(),y1=read(),x2=read(),y2=read();
    		L[i].p=(Node){x1,y1};L[i].v=(Node){x2,y2};
    		L[i].v=L[i].v-L[i].p;pL[i]=L[i];
    	}
    	double alpha=Pi/2-atan2(L[n+1].v.y,L[n+1].v.x);
    	for(int i=1;i<=n+1;++i)L[i].p=Turn(L[i].p,alpha);
    	for(int i=1;i<=n+1;++i)L[i].v=Turn(L[i].v,alpha);
    	for(int i=1;i<=n+1;++i)L[i].p=L[i].p-L[n+1].p;
    	for(int i=1;i<=n;++i)K[i]=L[i].v.y/L[i].v.x;
    	for(int i=1;i<=n;++i)G[i]=(Node){0,L[i].p.y-K[i]*L[i].p.x};
    	for(int i=1;i<=n;++i)id[i]=i;
    	sort(&id[1],&id[n+1],cmpid);
    	for(int i=1,top=0;i<=n;++i)
    	{
    		int x=id[i],l=1,r=top,ret=0;
    		while(l<=r)
    		{
    			int mid=(l+r)>>1;
    			if(K[x]>K[id[St[mid]]]&&!Parallel(pL[x],pL[id[St[mid]]]))ret=mid,r=mid-1;
    			else l=mid+1;
    		}
    		if(ret)cl[St[ret]]++,cl[i]--;
    		else St[++top]=i;
    	}
    	for(int i=1,top=0;i<=n;++i)
    	{
    		int x=id[i],l=1,r=top,ret=0;
    		while(l<=r)
    		{
    			int mid=(l+r)>>1;
    			if(K[x]<K[id[St[mid]]]&&!Parallel(pL[x],pL[id[St[mid]]]))ret=mid,r=mid-1;
    			else l=mid+1;
    		}
    		if(ret)cr[St[ret]]++,cr[i]--;
    		else St[++top]=i;
    	}
    	for(int i=1;i<=n;++i)cl[i]+=cl[i-1],cr[i]+=cr[i-1];cl[n+1]=cr[n+1]=0;
    	for(int i=n;~i;--i)
    		if(cl[i]&&cr[i])putchar(49);
    		else putchar(48);
    	return 0;
    }
    
  • 相关阅读:
    angular流程引擎集成
    angular打印功能实现方式
    文件hash、上传,实现文件上传重复验证
    HDU 6096 String(AC自动机+树状数组)
    HDU 5069 Harry And Biological Teacher(AC自动机+线段树)
    BZOJ 3172 单词(AC自动机)
    LightOJ 1268 Unlucky Strings(KMP+矩阵乘法+DP)
    Codeforces 808G Anthem of Berland(KMP+DP)
    LightOJ 1258 Making Huge Palindromes(KMP)
    UVA 11019 Matrix Matcher(哈希)
  • 原文地址:https://www.cnblogs.com/cjyyb/p/11165340.html
Copyright © 2020-2023  润新知