zoukankan      html  css  js  c++  java
  • 【*篇】luogu2778 [AHOI2016初中组]迷宫(代码高能!)

    好久好久我都没有刷题了。

    题目の传送门:https://www.luogu.org/problem/show?pid=2778

    题目大意:(啥 题目讲得不够清楚?)平面内有n个以整点(就是坐标都是整数的点啦~)为圆心、互不相交或相切的圆,现给出q组询问,查询连接两个整点至少要跨过多少圆。

    这题嘛,我们可以得出很显然的结论:
    1. 对于一个圆,如果A和B都不在圆内,则该圆可以被忽略。
    2. 对于一个圆,如果A和B都在圆内,则该圆可以被忽略。
    3. 一个圆被考虑,当且仅当AB二人中有且只有一人在圆内。

    然后我们就可以乱搞了= =
    我们对于每个询问,通过解析几何的公式暴力判断每个圆的求出点是否在圆内即可。
    公式:

    //设p为点,o为圆心
    dis(p,o)<=o.r
    dis(p,o)=sqrt(sqr(p.x-q.x)+sqr(p.y-q.y))

    对 就这样 时间复杂度O(nq),8000会卡(说好的大数据时限3s显然是tan(π/2))
    所以交上去会TLE 4个点,这时候就要手动开O3了(微笑)

    代码(呵呵,我就是故意的2333):

    QAQ ____{_w_ _,__,___;}OvO[o];QAQ ___{_w_ _,__;}OwO,O_O;_w_ w_v_w(___ _,____ __){w_w _(_._-__._)+_(_.__-__.__)<__.___;}
    _w_ main(){_w_ qwq,owo,TAT; _v_(qwq);_____(qwq){_v_(OvO[_]._);_v_(OvO[_].__);_v_(OvO[_].___);OvO[_].___*=OvO[_].___;}_v_(owo);_____(owo){TAT=ovo;_v_(OwO._);_v_(OwO.__); _v_(O_O._); _v_(O_O.__);_____(qwq)w_v_w(OwO,OvO[_])-w_v_w(O_O,OvO[_])?++TAT:ovo;v_v(TAT);}}

    什么,你说你看不懂?
    给你加点必要的提示?

    #define _(w)        ((w)*(w))
    #define QAQ         struct
    #define _w_         int
    #define w_w         return
    #define orz         main
    #define _v_(w)      scanf("%d",&w);
    #define v_v(w)      printf("%d
    ",w);
    #define o           8008
    #define _____(v)    for(int _=1;_<=v;_++)
    #define ovo         0

    加起来就是这样

    #include <cstdio>
    #define _(w)        ((w)*(w))
    #define QAQ         struct
    #define _w_         int
    #define w_w         return
    #define orz         main
    #define _v_(w)      scanf("%d",&w);
    #define v_v(w)      printf("%d
    ",w);
    #define o           8008
    #define _____(v)    for(int _=1;_<=v;_++)
    #define ovo         0
    QAQ ____{_w_ _,__,___;}OvO[o];QAQ ___{_w_ _,__;}OwO,O_O;_w_ w_v_w(___ _,____ __){w_w _(_._-__._)+_(_.__-__.__)<__.___;}
    _w_ main(){_w_ qwq,owo,TAT; _v_(qwq);_____(qwq){_v_(OvO[_]._);_v_(OvO[_].__);_v_(OvO[_].___);OvO[_].___*=OvO[_].___;}_v_(owo);_____(owo){TAT=ovo;_v_(OwO._);_v_(OwO.__); _v_(O_O._); _v_(O_O.__);_____(qwq)w_v_w(OwO,OvO[_])-w_v_w(O_O,OvO[_])?++TAT:ovo;v_v(TAT);}}

    什么,你说你还看不懂,算了我给你翻译一下吧(其实上面就是抖个机灵,不过我就是这么交的2333)。。

    #include <cstdio>
    #define sqr(a) ((a)*(a))
    struct circle{
        int x,y,r;
    }cir[8008];
    struct zb{
        int x,y;
    }a,b;
    int judge(zb u,circle v){
        return sqr(u.x-v.x)+sqr(u.y-v.y)<v.r; //这里的r是自乘过的(后面的处理),所以没有平方
    }i
    
    int main(){
        int q,n,s; scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d%d%d",&cir[i].x,&cir[i].y,&cir[i].r);
        scanf("%d",&q);
        for(int i=1;i<=q;i++){
            s=0;
            scanf("%d%d%d%d",&a.x,&a.y,&b.x,&b.y);
            for(int j=1;j<=n;j++){ //好吧其实我也不知道刚才玄学代码里面循环变量一样是怎么A掉的
                if(judge(a,cir[j])==judge(b,cir[j]));
                    else s++; //上面的玄学代码用三目运算符就是记这么写的……
            }
            printf("%d
    ",s);
        }
    }

    嗯 就是这样= =
    哦 题解里面还有一个官方std解法(显然那才是玄学解法嘛)

    转自luogu题解……
    作者: qq2477259579 更新时间: 2017-01-02 22:26

    把平面上每一个区域看作一个结点,最外层没有边界的区域也看作一个结点。如果一个区域刚好被另外一个区域直接包含,则连边。构成的图上做最短路径即可以得到40~60的分数。
    又发现,上述得到的图是树结构的,在树上预处理好任意两点的最近公共祖先,之后的询问可以线形完成,这便可以得到满分。
    哇 代码你们自己去题解里找吧,我理解能力有限_ (:з」∠) _

    我代码到底会不会写得更丑啊= =

  • 相关阅读:
    There is an overlap in the region chain修复
    There is an overlap in the region chain
    region xx not deployed on any region server
    python 中的re模块,正则表达式
    TCP粘包问题解析与解决
    yield from
    Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.
    mysql 中Varchar 与char的区别
    Mysql 字符集及排序规则
    请实现一个装饰器,限制该函数被调用的频率,如10秒一次
  • 原文地址:https://www.cnblogs.com/enzymii/p/8412146.html
Copyright © 2011-2022 走看看