题目链接在这里: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 ",ans[i]); 91 return 0; 92 }