Topic links:
http://acm.hdu.edu.cn/showproblem.php?pid=6731
Meaning of the questions:
N-$ $ given points, there are times $ Q $ query
Each time a point is given interrogation $ b $, which seek $ n + 1 $ points, the composition comprises a right triangle $ b $ and how many combinations
data range:
$ 1 \ leq n \ leq $ 2000
$ 1 \ leq q \ leq $ 2000
analysis:
Category talk
- When the interrogation points as a right angle. Let $ n $ points and $ b $ establish vector, where the vector into the most simple, find mutually perpendicular vectors, vector can be enumerated, seeking vertical vector
- When the initial point is given as a right angle, to the initial point of each offset vector is established, and then enumerate $ b $ points, mutually perpendicular vectors seek
Minimal vector, GCD first removed, if x is negative, the inverse of a vector, if x is 0, y is negative, the inverse of a vector, uniquely determined so that the direction of the vector
Note: int enough, longlong time out
There is also a quicker way: direct deposit x, y does not simplify, when comparing the vector, a direct comparison of the slope, i.e., greater than and less than that if the two vectors are equal
AC Code:
#include<bits/stdc++.h> #define ll long long #define pii pair<int,int> using namespace std; const int maxn=2007; pii a[maxn],b[maxn]; int n, q, years [maxn]; int mygcd(int a,int b){ if(b==0)return a; return mygcd(b,a%b); } pii getp(int x,int y){ int tem=mygcd(x,y); x / = tem, y / = tem; if(x<0)x=-x,y=-y; else if(x==0&&y<0)y=-y; return make_pair(x,y); } map<pii,int>ma; int main () { while(scanf("%d %d",&n,&q)==2){ for(int i=1;i<=n;i++)scanf("%d %d",&a[i].first,&a[i].second); for(int i=1;i<=q;i++)scanf("%d %d",&b[i].first,&b[i].second); for(int i=1;i<=q;i++){ ma.clear(); for(int j=1;j<=n;j++){ int x=a[j].first-b[i].first,y=a[j].second-b[i].second; ma[getp(x,y)]++; if(ma.count(getp(-y,x)))ans[i]+=ma[getp(-y,x)]; } } // for(int i=1;i<=q;i++)printf("%d\n",ans[i]),ans[i]=0; //cout<<"cdsafa"<<endl; for(int i=1;i<=n;i++){ ma.clear(); for(int j=1;j<=n;j++){ if(j==i)continue; int x=a[j].first-a[i].first,y=a[j].second-a[i].second; ma[getp(x,y)]++; } for(int j=1;j<=q;j++){ int x=b[j].first-a[i].first,y=b[j].second-a[i].second; if(ma.count(getp(-y,x)))ans[j]+=ma[getp(-y,x)]; } } for(int i=1;i<=q;i++)printf("%d\n",ans[i]),ans[i]=0; } return 0; }