好吧,和这道题刚了一下午,虽然说很累,但最后A了还是很开心。
一开始自信自己能够A掉这道题,就连续换了几种姿势,写了几份代码,最后还是T了 ,不得不借助标程才发现原来是自己把判断是否平行的条件写复杂了
收获:
1.在判断两直线是否平行的时候,最好采用一次函数,而且并不复杂,虽然计算机有浮点数精度误差,但是对于一般题目还是搓搓有余了。而且每次判断是否相等的时候 用 a-b<1e-6来代替 a==b 保证不坑
2.有时候,得向标程认怂,不为别的,因为从题解还是可以学到很多有用的东西
#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 2020
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
LL n;
struct node{
LL x, y;
bool operator < (const node& b) const{
return x==b.x?y<b.y:x<b.x ;
}
}nod[maxn];
LL cnt;
struct edge{
int len;
double k,b;
bool operator <(const edge& b)const{
if(fabs(k-b.k)>1e-6){
return k<b.k;
}
else return len<b.len;
}
}e[maxn*maxn];
int check(int a,int b){
return fabs(e[a].k-e[b].k)<1e-6&&e[a].len==e[b].len;
}
int main(){
scanf("%lld",&n);
LL x,y;
for(LL i=1;i<=n;i++){
scanf("%lld%lld",&x,&y);
nod[i].x=x;nod[i].y=y;
}
sort(nod+1,nod+1+n);
nod[0].x=-12,nod[0].y=-5;
int k=0;
for(int i=1;i<=n;i++){
if(nod[i].x==nod[k].x&&nod[i].y==nod[k].y )continue;
nod[++k]=nod[i];
}
for(LL i=1;i<=k;i++){
for(LL j=i+1;j<=k;j++){
int x=nod[i].x-nod[j].x;
int y=nod[i].y-nod[j].y ;
e[++cnt].len=(x*x)+y*y;
if(nod[i].x==nod[j].x){
e[cnt].k=1e9*1.0;
e[cnt].b=nod[i].x;
}
else {
e[cnt].k=(nod[i].y-nod[j].y )*1.0/(nod[i].x-nod[j].x)*1.0;
e[cnt].b=nod[i].y-e[cnt].k*nod[i].x;
}
}
}
LL ans=0;
sort(e+1,e+1+cnt);
for(LL i=1;i<=cnt;){
int j;
for(j=i+1;j<=cnt;j++){
if(!check(i,j))break;
}
for(int l=i;l<j;l++){
for(int m=l+1;m<j;m++){
if(fabs(e[l].b-e[m].b)>1e-6)ans++;
}
}
i=j;
}
printf("%lld",ans/2);
return 0;
}