zoukankan      html  css  js  c++  java
  • LOJ 2882. 「JOISC 2014 Day4」两个人的星座

    LOJ 2882. 「JOISC 2014 Day4」两个人的星座

    对于任意两个凸多边形相离,一定可以找到一条直线将它们分在平面的两个区域

    而对于三角形的情况更为特殊

    分析可以发现,很难直接枚举三角形外直线计算,而对于任意的两个合法的三角形,在其6点中较近的4个点中

    一定可以从两个三角形中各选一个点,连出两条交错的合法的分界线,例如下图

    QQ截图20201102153211.png

    那么可以考虑枚举这样的一条直线,即确定了两个分界线上的端点,然后从两个半平面内选出不同颜色的点

    直接枚举,然后(O(n))数出这样的点,复杂度为(O(n^3))

    显然可以想到枚举一个顶点,然后对于其他极角排序,旋转另一个点,同步统计半平面内的点个数,复杂度为(O(n^2log n))

    实现上,可以枚举一个点,尺取一个半平面内的点

    #include<bits/stdc++.h>
    using namespace std;
    using ll=int64_t;
    enum{N=3010};
    int n,X[N],Y[N],I[N],C[N],c,s[2][3],i;
    double T[N];
    ll ans;
    ll E(int j,int k){ return 1ll*(X[j]-X[i])*(Y[k]-Y[i])-1ll*(Y[j]-Y[i])*(X[k]-X[i]); }
    
    int main(){
    	for(int i=scanf("%d",&n);i<=n;++i) scanf("%d%d%d",X+i,Y+i,C+i);
    	for(i=1;i<=n;++i) {
    		c=0;
    		memset(s,0,sizeof s);
    		for(int j=1;j<=n;++j) if(i!=j) I[++c]=j,T[j]=atan2(Y[j]-Y[i],X[j]-X[i]),s[0][C[j]]++;
    		sort(I+1,I+n,[&](int x,int y){ return T[x]<T[y]; });
    		int p=1;
    		for(int j=1;j<n;++j) {
    			while(E(I[j],I[p])>=0) {
    				s[0][C[I[p]]]--,s[1][C[I[p]]]++;
    				p=p%c+1;
    				if(p==j) break;
    			}
    			ans+=1ll*s[0][(C[i]+1)%3]*s[0][(C[i]+2)%3]*s[1][(C[I[j]]+1)%3]*s[1][(C[I[j]]+2)%3];
    			s[1][C[I[j]]]--,s[0][C[I[j]]]++;
    		}
    	}
    	cout<<ans/2;
    }
    

    一个更好的写法是把在(y)轴以下的点中心对称上来,统计时每跨过一个点改变一次

    #include<bits/stdc++.h>
    using namespace std;
    enum{N=3010};
    int n,X[N],Y[N],C[N],c,s[2][3],i,j,d,a,b,x,y;
    int64_t ans;
    struct Node{
    	int x,y,d,c;
    	Node(){}
    	Node(int p,int q,int r) {
    		x=p,y=q,c=r,d=0;
    		if(y<0||(x<0&&y==0)) d=1,x=-x,y=-y; 
    		s[d][c]++;
    	}
    } A[N];
    struct cmp{ int operator () (const Node &a,const Node &b){ return 1ll*a.x*b.y<1ll*a.y*b.x; }};
    int main(){
    	for(i=scanf("%d",&n);i<=n;++i) scanf("%d%d%d",X+i,Y+i,C+i);
    	for(i=1;i<=n;++i) {
    		memset(s,c=0,sizeof s),a=(C[i]+1)%3,b=(a+1)%3;
    		for(j=1;j<=n;++j) if(i!=j) A[++c]=Node(X[j]-X[i],Y[j]-Y[i],C[j]);
    		for(sort(A+1,A+n,cmp()),j=1;j<n;++j) {
    			s[A[j].d][c=A[j].c]--,x=(c+1)%3,y=(x+1)%3;
    			for(d=0;d<2;++d) ans+=1ll*s[d][a]*s[d][b]*s[!d][x]*s[!d][y];
    			s[!A[j].d][c]++;
    		}
    	}
    	cout<<ans/4;
    }
    
  • 相关阅读:
    关于 OpenSmtp 邮件标题过长后出现乱码问题的解决
    用于解析 sohu 新闻页面的 XSLT 文件
    CEGUI 0.7x实现下划线描边图文混排等效果
    Hash算法说明
    D3DXMatrixShadow 函数
    DLL动态链接库和LIB静态链接库之程序员经验分析
    printf格式控制符的完整格式(转载)
    深入说明HDR技术
    Irrlicht不定期分析
    8.3实例程序:平面阴影
  • 原文地址:https://www.cnblogs.com/chasedeath/p/13914978.html
Copyright © 2011-2022 走看看