【HDU 6731】2019 CCPC秦皇岛 A题(计算几何)

Problem Description
Given n points P1P2, .... , 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 , PuPv 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.
 

 

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
 
 
 

【题目大意】
 给定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 }
View Code

 

 

posted @ 2019-10-09 16:19  rentu  阅读(617)  评论(0编辑  收藏  举报