题目链接在这里:​​Problem - A - Codeforces​

这道几何题根据数据范围只支持O(n2)的复杂度,意思就是最多只能枚举两个点。由于直角边的向量之积为0,所以我们可以通过一个向量算出对应的与之垂直的向量,这样我们每次固定一个点,把当前点所能连出的向量都枚举一遍,再统计一遍就行了。注意直角三角形会有两种情况,一种是问的点是直角顶点,一种是问的点不是直角顶点。两种情况都要统计。

这题要注意的地方有两点

一个是向量要保证格式统一,都要除以gcd并且第一个值要保证为正值,如果有零另外一个也应为正值。

一个是由于map是一个红黑树,所以不能开太大,map尽量不要再开一个数组。并且判断当前元素是否之前出现在map中应该用

if (q.find((Vec){dx,dy})!=q.end())来判断,不能直接判断是否等于0。不然就相当于重新开了个空间,会出现奇怪的问题。

1 #include "bits/stdc++.h"
2 #define mp(a,b) (Vec){a,b}
3 #define fi first
4 #define se second
5 using namespace std;
6 typedef long long LL;
7 const int MAX=2005;
8 LL n,m;
9 LL x[MAX],y[MAX],qx[MAX],qy[MAX];
10 LL ans[MAX];
11 struct Vec{
12 LL x,y;
13 };
14 bool operator <(Vec rr,Vec tt){
15 if (rr.x!=tt.x) return rr.x<tt.x;
16 return rr.y<tt.y;
17 }
18 map <Vec,LL> q;
19 inline LL gcd(LL cc,LL vv){return (vv==0?cc:gcd(vv,cc%vv));}
20 int main(){
21 freopen ("a.in","r",stdin);
22 freopen ("a.out","w",stdout);
23 LL i,j,zt,gg;
24 LL zx,zy,cx,cy;
25 scanf("%lld%lld",&n,&m);
26 for (i=1;i<=n;i++) scanf("%lld%lld",x+i,y+i);
27 for (i=1;i<=m;i++) scanf("%lld%lld",qx+i,qy+i);
28 for (i=1;i<=m;i++){
29 q.clear();
30 for (j=1;j<=n;j++){
31 zx=x[j]-qx[i];
32 zy=y[j]-qy[i];
33 gg=gcd(abs(zx),abs(zy));
34 if (gg!=0) zx/=gg,zy/=gg;
35 if (zx<0) zx*=-1,zy*=-1;
36 if (zx==0) zy=abs(zy);
37 if (zy==0) zx=abs(zx);
38 q[mp(zx,zy)]++;
39 }
40 zt=0;
41 for (j=1;j<=n;j++){
42 zx=x[j]-qx[i];
43 zy=y[j]-qy[i];
44 gg=gcd(abs(zx),abs(zy));
45 if (gg!=0) zx/=gg,zy/=gg;
46 if (zx<0) zx*=-1,zy*=-1;
47 if (zx==0) zy=abs(zy);
48 if (zy==0) zx=abs(zx);
49 cx=-zy;
50 cy=zx;
51 if (cx==0) cy=abs(cy);
52 if (cy==0) cx=abs(cx);
53 if (cx<0) cx*=-1,cy*=-1;
54 if (q.find(mp(cx,cy))!=q.end())
55 zt+=q[mp(cx,cy)];
56 }
57 ans[i]+=zt/2;
58 }
59 for (i=1;i<=n;i++){
60 q.clear();
61 for (j=1;j<=n;j++){
62 if (i==j) continue;
63 zx=x[j]-x[i];
64 zy=y[j]-y[i];
65 gg=gcd(abs(zx),abs(zy));
66 if (gg!=0) zx/=gg,zy/=gg;
67 if (zx<0) zx*=-1,zy*=-1;
68 if (zx==0) zy=abs(zy);
69 if (zy==0) zx=abs(zx);
70 q[mp(zx,zy)]++;
71 }
72 for (j=1;j<=m;j++){
73 zx=x[i]-qx[j];
74 zy=y[i]-qy[j];
75 gg=gcd(abs(zx),abs(zy));
76 if (gg!=0) zx/=gg,zy/=gg;
77 if (zx<0) zx*=-1,zy*=-1;
78 if (zx==0) zy=abs(zy);
79 if (zy==0) zx=abs(zx);
80 cx=-zy;
81 cy=zx;
82 if (cx==0) cy=abs(cy);
83 if (cy==0) cx=abs(cx);
84 if (cx<0) cx*=-1,cy*=-1;
85 if (q.find(mp(cx,cy))!=q.end())
86 ans[j]+=q[mp(cx,cy)];
87 }
88 }
89 for (i=1;i<=m;i++)
90 printf("%lld\n",ans[i]);
91 return 0;
92