AT_abc418_e 题解
题目传送门
题意
平面内有
思路
因为一组对边平行的四边形是四边形,那么在平面中斜率相同的边平行,就可以组成梯形。注意到
然而上述的式子并不是答案,因为存在两组对边互相平行的平行四边形,这也导致平行四边形的数量被计算了
最终时间复杂度略大于
注意事项
- 斜率注意统一格式,即要给坐标
x 与y 通分,以及统一负号的位置。 - 建议使用
unordered_map代替map,减小代码常数。 - 不开
long long见祖宗。
AC CODE
#include<bits/stdc++.h>
using namespace std;
#define int long long
int read(){int x=0;char f=1,ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();return x*f;}
const int N=2e3+10,INF=1e9;
int x[N],y[N];
struct node{
int u,v;
};
int to(int u,int v){
return u*INF+v;
}
node bk(int x){
return (node){x/INF,x%INF};
}
unordered_map<int,vector<node>>mp;
signed main(){
int n=read();
for(int i=1;i<=n;++i)
x[i]=read(),y[i]=read();
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j){
int dx=x[i]-x[j],dy=y[i]-y[j];
if(!dx&&!dy)
continue;
int _gcd=__gcd(dx,dy);
dx/=_gcd,dy/=_gcd;
if(dx<0||!dx&&dy<0)
dx=-dx,dy=-dy;
mp[to(dx,dy)].push_back({i,j});
}
int cnt=0;
for(auto[u,v]:mp){
unordered_map<int,int>t;
for(auto[x,y]:v)
++t[x],++t[y];
int sum=0;
for(auto[x,y]:t)
sum+=y*(y-1)/2;
int l=v.size();
cnt+=l*(l-1)/2-sum;
}
unordered_map<int,int>t;
for(int i=1;i<=n;++i)
for(int j=i+1;j<=n;++j){
int sx=x[i]+x[j],sy=y[i]+y[j];
++t[to(sx,sy)];
}
int res=0;
for(auto[u,v]:t)
res+=v*(v-1)/2;
printf("%lld\n",cnt-res);
return 0;
}