Day7 T1 right triangle

topic

A two-dimensional plane coordinate system has N points. 3 points selected from N points, asked how many such method is selected from these three points form a right triangle.

Entry

The first row contains an integer N (. 3 \ (\ leqslant \) N \ (\ leqslant \) 1500), number of dots.
Next N rows, each row comprising two integers separated by a space coordinates of each point represent the coordinate values in \ (- 10 ^ 9 \) to \ (10 ^ 9 \) between. Each point different from each other.

Export

Output of the number of right-angled triangle.

Sample

Entry Export
3
4 2
2 1
1 3
1
4
5 0
2 6
8 6
5 7
0
5
-1 1
-1 0
0 0
1 0
1 1
7

answer

A fixed point P, the entire translated coordinate system, such as the origin P. Now, for each point, in which it is determined first quadrant, then rotate k • 90 ° (k∈Z), it falls in the first quadrant. Thereafter, according to the slope k a direct proportion function over point (ordinate divided abscissa) sort all points. If the same two point slope and adjacent quadrants, they can form a right triangle at a right angle vertex P before the rotation. After sorting, the same slope for each set of points, the number of statistics in their original point of each quadrant, and quadrant multiplying the number of neighboring points. Time complexity is \ (O (N ^ 2logN) \) . (This is why \ (O (N ^ 3) \) the enumeration of violence after adding a bunch of metaphysics optimization can be jammed: because the time complexity of the positive solution is not low)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int x[1510],y[1510];
ll ans=0;

struct node{
    ll x,y;
    int qua;
};
node cpy[1510];

bool cmp(node a,node b){
    return a.y*b.x<a.x*b.y;
    //将不等式变形成两边都是乘法运算,避免除法运算带来的精度损失
}

void rotate(int m){
    if(cpy[m].x==0 && cpy[m].y==0) return;//如果是原点,无需旋转
    cpy[m].qua=1;
    while(cpy[m].x<=0 || cpy[m].y<0){
        swap(cpy[m].x,cpy[m].y);
        cpy[m].y=-cpy[m].y;
        cpy[m].qua++;//如果一个点需要顺时针旋转n次才落在第一象限,那么其原象限为n+1 
        //最多旋转3次(原来在第四象限),所以这里无需像隔壁熊泽恩同学写的那样取模 
    }
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d %d",&x[i],&y[i]);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cpy[j].x=x[j]-x[i];
            cpy[j].y=y[j]-y[i];
            rotate(j);
        }
        swap(cpy[1],cpy[i]);//不要把原点给算进去了
        sort(cpy+2,cpy+n+1,cmp);
        int j=2;
        while(j<=n){
            int cnt[5]={0};
            int k=j;
            while(k<=n && cpy[j].y*cpy[k].x==cpy[j].x*cpy[k].y){
                cnt[cpy[k].qua]++;
                k++;
            }
            for(int t=1;t<4;t++) ans+=cnt[t]*cnt[t+1];
            ans+=cnt[1]*cnt[4];
            j=k;
        }
    }
    printf("%lld",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/znk161223/p/11516691.html