• 周五. 10月 7th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

暑假集训Day19 A (几何)

admin

11月 28, 2021

题目链接在这里: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 }
未来是什么样,未来会发生什么,谁也不知道。
但是我知道,
起码从今天开始努力,
肯定比从明天开始努力,
要快一天实现梦想。
千里之行,始于足下! ——《那年那兔那些事儿》

发表回复

您的电子邮箱地址不会被公开。