Problem Description
Given n points
P1, P2, .... , Pn on 2D plane and q queries. In i-th query, a point Ai is given, and you should determine the number of tuples (u, v) that 1 ≤ u < v ≤ n and Ai , Pu, Pv form a non-degenerate right-angled triangle.
Input
The first line contains two positive integers n, q (2 ≤ n ≤ 2 000, 1 ≤ q ≤ 2 000), denoting the numberof given points and the number of queries.
Next n lines each contains two integers xi , yi (|xi|, |yi| ≤ 109), denoting a given point Pi.
Next q lines each contains two integers xi , yi (|xi|, |yi| ≤ 109), denoting a query point Ai.
It is guaranteed that the input n + q points are all pairwise distinct.
Next n lines each contains two integers xi , yi (|xi|, |yi| ≤ 109), denoting a given point Pi.
Next q lines each contains two integers xi , yi (|xi|, |yi| ≤ 109), denoting a query point Ai.
It is guaranteed that the input n + q points are all pairwise distinct.
Output
Output q lines each contains a non-negative integer, denoting the answer to corresponding query.
Sample Input
4 2 0 1 1 0 0 -1 -1 0 0 0 1 1
Sample Output
4 3
View Code
【题目大意】
给定n个点的x,y,再给定 q 个点,对每个点有一次询问,询问由这个点和前 n 个点能形成多少个直角三角形
【算法分析】
解题思路其实场上已经想的差不多了,但是败在做题少,实现有困难上了
(还是做题太少啊,菜哭)
分两种情况:
一种是询问点是直角顶点
一种是询问点不是直角顶点
对两种情况,分别枚举,向前 n 个点连边,极角排序
然后再对每个边枚举,直接查看和他垂直的直线是否存在
对第二种情况特殊处理下,只是查询的点略微有些差别
对 map 的一些新理解:
只需要重载 < 就能够实现 > 和 ==
【代码】
1 #include<cstdio> 2 #include<map> 3 #include<cstring> 4 #define ll long long 5 using namespace std; 6 const int MAXN = 2005; 7 struct P 8 { 9 ll x, y; 10 P(ll a=0,ll b=0) 11 { 12 x = a, y = b; 13 }; 14 P base()const 15 { 16 if (x < 0 || (x == 0 && y < 0)) return P(-x, -y); 17 return *this; 18 } 19 P operator-(const P &a) const 20 { 21 return P(x - a.x, y - a.y); 22 } 23 bool operator<(const P &a)const 24 { 25 P p1 = base(), p2 = a.base(); 26 return p1.x*p2.y < p2.x*p1.y; 27 } 28 29 }p[MAXN],q[MAXN]; 30 map<P, int> mapp; 31 ll ans[MAXN]; 32 int main() 33 { 34 int N,Q; 35 while (~scanf("%d%d", &N, &Q)) 36 { 37 memset(ans, 0, sizeof(ans)); 38 for (int i = 1; i <= N; i++) scanf("%lld %lld", &p[i].x, &p[i].y); 39 for (int i = 1; i <= Q; i++) scanf("%lld %lld", &q[i].x, &q[i].y); 40 for (int i = 1; i <= Q; i++) 41 { 42 mapp.clear(); 43 for (int j = 1; j <= N; j++) 44 mapp[(p[j] - q[i])]++; 45 for (int j = 1; j <= N; j++) 46 { 47 P req = p[j] - q[i]; 48 req = P(-req.y, req.x); 49 ans[i] += mapp.count(req) ? mapp[req] : 0; 50 } 51 ans[i] /= 2; 52 } 53 for (int i = 1; i <= N; i++) 54 { 55 mapp.clear(); 56 for (int j = 1; j <= N; j++) 57 if (i != j) mapp[(p[j] - p[i])]++; 58 for (int j = 1; j <= Q; j++) 59 { 60 P req = q[j] - p[i]; 61 req = P(-req.y, req.x); 62 ans[j] += mapp.count(req) ? mapp[req] : 0; 63 } 64 } 65 for (int i = 1; i <= Q; i++) 66 { 67 printf("%lld\n", ans[i]); 68 } 69 } 70 return 0; 71 }