1 条题解
-
0
计算几何纯码力题。
对于每一对合法的三角形,有且仅有两条顶点之间的连线使得三角形被切割在左右(上下)两侧。如图所示。

考虑固定一个顶点,将其他的点极角排序,然后按顺序枚举另一个顶点,用一个指针维护两个半平面三种颜色的点的数量。
#include<bits/stdc++.h> #define int long long//计算几何爆int? using namespace std; const int N=2e5+5; struct node{ int x,y,c; int operator*(node B)const{ return x*B.y-y*B.x; } }a[N],b[N]; int n,ans; signed main(){ ios::sync_with_stdio(0);cin.tie(0); cin>>n; for(int i=1;i<=n;i++)cin>>a[i].x>>a[i].y>>a[i].c; for(int i=1;i<=n;i++){ for(int j=1,tot=0;j<=n;j++) if(i!=j)b[++tot]={a[j].x-a[i].x,a[j].y-a[i].y,a[j].c};//以当前点为原点重新建系 sort(b+1,b+n,[](node A,node B){ if(!A.x&&!A.y)return true; if(!B.x&&!B.y)return false; return atan2(A.y,A.x)>atan2(B.y,B.x);//极角排序 }); int s[2][4]={0,0,0,0,0,0,0,0},pos=1;//sum,指针 s[1][b[1].c]++,s[0][a[i].c]++; for(int j=2;j<n;j++)s[0][b[j].c]++; while(pos<n-1&&b[1]*b[pos+1]<=0) pos++,s[0][b[pos].c]--,s[1][b[pos].c]++; ans+=s[0][0]*s[0][1]*s[0][2]/s[0][a[i].c]*s[1][0]*s[1][1]*s[1][2]/s[1][b[1].c]; //统计在第一个顶点的答案 for(int j=2;j<n;j++){ s[1][b[j-1].c]--,s[0][b[j-1].c]++; while(1){ if(pos==n-1)pos=0; if(b[j]*b[pos+1]>0||(pos+1==j&&s[1][b[j].c]>0))break; pos++,s[0][b[pos].c]--,s[1][b[pos].c]++;//移动指针 } ans+=s[0][0]*s[0][1]*s[0][2]/s[0][a[i].c]*s[1][0]*s[1][1]*s[1][2]/s[1][b[j].c]; } } cout<<ans/2;//一对三角形会被两条直线统计 return 0; }
- 1
信息
- ID
- 5911
- 时间
- 9000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者