• 暑假集训Day19 A (几何)


    题目链接在这里: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 }
    未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
  • 相关阅读:
    【开源】知乎日报UWP 更新
    【开源】知乎日报UWP 更新
    耿丹学院软工助教(2016年上半年)
    c++ STL map 结构体
    2016搜狐笔试二叉树和最大的子树
    从B树、B+树、B*树谈到R 树
    C++继承:公有,私有,保护
    循环队列
    C++中的static关键字
    c++map的用法
  • 原文地址:https://www.cnblogs.com/keximeiruguo/p/15139288.html
Copyright © 2020-2023  润新知