数三角题解报告
数三角
http://www.nowcoder.com/questionTerminal/06763b319e75433daea6f24e99d47d03
一种十分暴力的暴力
首先我们枚举3个点。
我们知道,这3个点可能构成三角形或一条线。
我们需要把线的情况判掉,剩下的三角形再通过一些手段判断出是否为钝角三角形。
对于三个点x(x1,y1),y(x2,y2),z(x3,y3)
我们以x为原点重新构造坐标系,那么此时y(x2-x1,y2-y1),z(x3-x1,y3-y1)
我们选用x和y构造正比例函数(过原点,因为此时x是原点),如果z在这个函数上,那么三点为一条直线
那么我们知道如果,那么z在xy这条线上
此时直接除会有精度问题,(我不知道数据有没有卡),那么利用等式的性质上面的式子可以变为:
这样就不会有精度上的问题
那么我们再来想如何判断钝角三角形。
我们先瞎搞一个钝角三角形,然后作一下高
延长BC到D,过A点作AE垂直于CD,我们就得到直角和
我们知道
即
也为
我们也知道
所以
应为
因此
这里的AC是最长边,AB和BC是两条短边,所以我们求得最长边的平方,与两短边的平方比较即可
贴上蒟蒻代码:
#include<bits/stdc++.h> #define maxn 510 using namespace std; int n,ans; struct drop{ int x,y; }a[maxn],nx,ny,nz; int check(int x,int y,int z){ nx.x=0,nx.y=0; ny.x=a[y].x-a[x].x,ny.y=a[y].y-a[x].y; nz.x=a[z].x-a[x].x,nz.y=a[z].y-a[x].y; if(ny.x*nz.y==ny.y*nz.x) return 0; long long e1,e2,e3; e1=(a[x].x-a[y].x)*(a[x].x-a[y].x)+(a[x].y-a[y].y)*(a[x].y-a[y].y); e2=(a[x].x-a[z].x)*(a[x].x-a[z].x)+(a[x].y-a[z].y)*(a[x].y-a[z].y); e3=(a[y].x-a[z].x)*(a[y].x-a[z].x)+(a[y].y-a[z].y)*(a[y].y-a[z].y); long long max_e=max(e1,max(e2,e3)); if((e1+e2<max_e&&max_e==e3)||(e2+e3<max_e&&max_e==e1)||(e1+e3<max_e&&max_e==e2)) return 1; return 0; } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d%d",&a[i].x,&a[i].y); for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) for(int p=j+1;p<=n;++p) ans+=check(i,j,p); printf("%d",ans); return 0; }