其他分享
首页 > 其他分享> > [JOISC2014]二人の星座

[JOISC2014]二人の星座

作者:互联网

XVI.[JOISC2014]二人の星座

这题乍一看,和之前X.[POI2008]TRO-Triangles好像思想差不多;但是实际操作一番并进行了很多失败的尝试后,发现并不能简单应用。

后来知道了一种判两个(三点不共线的)三角形相离的做法:它们一定存在且只存在两条相同的外割线。(一个三角形的外割线指的是经过其一个顶点且只在该顶点处与整个三角形相交的直线;相同的外割线,就是经过两个三角形各一个节点的上述直线)。具体可以通过画几个三角形自己手工感性理解一下。

知道该结论就行了。我们考虑枚举该外割线即可(可以通过固定外割线的一端,按照极角大小排序并枚举另一端实现),然后考虑该外割线两端各有多少对节点可以分别与两个端点构成三角形即可。具体操作参见X即可。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ms(x) memset(x,0,sizeof(x))
typedef long long ll;
int n,m,col[3010],ss[3],in[3];
ll res;
const double pi=acos(-1);
struct Vector{
	int x,y;
	Vector(int X=0,int Y=0){x=X,y=Y;}
	friend Vector operator +(const Vector &u,const Vector &v){return Vector(u.x+v.x,u.y+v.y);}
	friend Vector operator -(const Vector &u,const Vector &v){return Vector(u.x-v.x,u.y-v.y);}
	friend ll operator &(const Vector &u,const Vector &v){return 1ll*u.x*v.y-1ll*u.y*v.x;}//cross times
	friend ll operator |(const Vector &u,const Vector &v){return 1ll*u.x*v.x+1ll*u.y*v.y;}//point times
	double operator !()const{return atan2(y,x);}//the angle of a vector
	friend bool operator <(const Vector &u,const Vector &v){return !u<!v;}
	void read(){scanf("%d%d",&x,&y);}
	void print(){printf("(%d,%d)",x,y);}
}p[3010];
typedef Vector Point;
pair<Point,int>q[3010];
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++)p[i].read(),scanf("%d",&col[i]),ss[col[i]]++;
	for(int i=0;i<n;i++){
		m=0;
		for(int j=0;j<n;j++)if(i!=j)q[m++]=make_pair(p[j]-p[i],col[j]);
		sort(q,q+m);
//		for(int j=0;j<m;j++)q[j].first.print();puts("");
		int len=-1;
		for(int a=0,b=0;a<m;a++){
			in[q[a].second]--;
			if(len<0)ms(in),len=0,b=(a+1)%m;
			for(;len<m&&(q[a].first&q[b].first)>0;b=(b+1)%m)in[q[b].second]++,len++;
//			printf("[%d,%d]\n",a,b);
//			for(int j=0;j<3;j++)printf("%d ",in[j]);puts("");
//			for(int j=0;j<3;j++)printf("%d ",ss[j]-in[j]-(q[a].second==j)-(col[i]==j));puts("");
			ll now=1;
			for(int j=0;j<3;j++)if(j!=col[i])now*=in[j];
			for(int j=0;j<3;j++)if(j!=q[a].second)now*=(ss[j]-in[j]-(col[i]==j));
			res+=now; 
			len--;
		}
	}
	printf("%lld\n",res>>1);
	return 0;
} 

标签:JOISC2014,const,int,割线,operator,Vector,星座,return,二人
来源: https://www.cnblogs.com/Troverld/p/14619360.html