链接:https://ac.nowcoder.com/acm/contest/52441/E 来源:牛客网 给定n 个不重复的坐标,求其中 3个坐标能表示一个等腰三角形的组数。 三点共线不算三角形,等边三角形为特殊的等腰三角形。用c++实现
时间: 2023-05-25 11:02:39 浏览: 259
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=10005;
const double eps=1e-8;
struct point
{
double x,y;
friend bool operator<(const point &a,const point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
friend point operator+(const point &a,const point &b)
{
return point{a.x+b.x,a.y+b.y};
}
friend point operator-(const point &a,const point &b)
{
return point{a.x-b.x,a.y-b.y};
}
friend point operator*(const point &a,double b)
{
return point{a.x*b,a.y*b};
}
friend point operator/(const point &a,double b)
{
return point{a.x/b,a.y/b};
}
friend double operator*(const point &a,const point &b)
{
return a.x*b.y-a.y*b.x;
}
}p[N],st[N],st2[N];
int top=0,top2=0,n,ans;
double len[N],sum[N];
inline double dist(const point &a,const point &b)
{
double x=a.x-b.x,y=a.y-b.y;
return sqrt(x*x+y*y);
}
inline void tubao()
{
for(int i=1;i<=n;++i)
{
while(top&&p[i].y<=st[top].y) --top;
st[++top]=p[i];
}
for(int i=1;i<=n;++i)
{
while(top2&&p[i].y>=st2[top2].y) --top2;
st2[++top2]=p[i];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%lf%lf",&p[i].x,&p[i].y);
sort(p+1,p+n+1);
tubao();
for(int i=1;i<=top;++i)
st[i+top]=st[i];
for(int i=1,j=1,k=1;i<=top;++i)
{
while(dist(st[i],st[j])<dist(st[i],st[j+1]))
j=j%top+1;
while(k+1<i+top&&((st[i]-st[j])*(st[i]-st[k+1]))>((st[i]-st[j])*(st[i]-st[k])))
k=k%top+1;
len[i]=dist(st[i],st[j]);
sum[i]=sum[i-1]+len[i];
while(sum[i]-sum[j-1]>len[i]+eps) ++j;
if(st[i].y==st[j].y) continue;
double a=dist(st[i],st[j]),b=dist(st[j],st[k]),c=dist(st[i],st[k]),p=(a+b+c)/2;
if(fabs(b*b+c*c-a*a)<eps)
ans+=upper_bound(sum+i,sum+top2+1,sum[i-1]+len[i]/2)-lower_bound(sum+i,sum+top2+1,sum[i-1]-len[i]/2);
else continue;
}
printf("%d\n",ans);
return 0;
}
阅读全文