• LOJ#2882. 「JOISC 2014 Day4」两个人的星座(计算几何)


    题面

    传送门

    题解

    我们发现如果两个三角形相离,那么这两个三角形一定存在两条公切线

    那么我们可以(O(n^2))枚举其中一条公切线,然后可以暴力(O(n^3))计算

    怎么优化呢?我们可以枚举一个定点,然后把其它所有点按到这个定点的极角排序,那么就可以(O(n^2))得出答案了

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define ll long long
    #define inline __inline__ __attribute__((always_inline))
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=3005;const double Pi=acos(-1.0);
    int c[2][5],bl[N],n;ll res;
    struct node{
    	int x,y,c;double k;
    	inline node(){}
    	inline node(R int xx,R int yy):x(xx),y(yy){}
    	inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
    	inline double K(){return atan2(y,x);}
    	inline bool operator <(const node &b)const{return k<b.k;}
    }st[N],p[N];
    inline int calc(R int k,R int x){
    	switch(x){
    		case 0:return c[k][1]*c[k][2];break;
    		case 1:return c[k][0]*c[k][2];break;
    		case 2:return c[k][0]*c[k][1];break;
    	}
    }
    void solve(int id){
    	int top=0;
    	fp(i,1,id-1)p[++top]=st[i],p[top].k=(st[i]-st[id]).K();
    	fp(i,id+1,n)p[++top]=st[i],p[top].k=(st[i]-st[id]).K();
    	fp(i,1,top)if(p[i].k<=0)p[i].k+=Pi;
    	sort(p+1,p+1+top);
    	c[0][0]=c[0][1]=c[0][2]=c[1][0]=c[1][1]=c[1][2]=0;
    	fp(i,1,top)if(p[i].y<st[id].y||p[i].y==st[id].y&&p[i].x>st[id].x)
    		++c[0][p[i].c],bl[i]=0;
    	else ++c[1][p[i].c],bl[i]=1;
    	fp(i,1,top){
    		--c[bl[i]][p[i].c],res+=1ll*calc(0,st[id].c)*calc(1,p[i].c);
    		res+=1ll*calc(1,st[id].c)*calc(0,p[i].c),bl[i]^=1,++c[bl[i]][p[i].c];
    	}
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	n=read();
    	fp(i,1,n)st[i].x=read(),st[i].y=read(),st[i].c=read();
    	fp(i,1,n)solve(i);
    	printf("%lld
    ",res>>2);
    	return 0;
    }
    
  • 相关阅读:
    TClientDataSet[6]: 读取 TClientDataSet 中的图片数据
    TClientDataSet[2]: Data、XMLData
    TClientDataSet[5]: 读取数据
    TClientDataSet[1]: 浏览测试数据
    TClientDataSet[3]: 手动建立数据集
    从哪查找当前程序所有可用的环境变量?
    使用多窗体时, 关于节约内存和加快启动速度的思考与尝试
    一句话获取文件的最新修改时间
    用 SuperObject 解析淘宝上的 Json 数据 回复 "macrolen" 的问题
    “生气”的经典解释
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10706830.html
Copyright © 2020-2023  润新知