zoukankan      html  css  js  c++  java
  • BZOJ4437 : [Cerc2015]Looping Labyrinth

    从$(0,0)$开始BFS$2 imes10^6$步,那么迷宫的形状有三种:

    1.走不完$2 imes10^6$步,直接判定即可。

    2.可以走到$(n,0)$以及$(0,m)$,那么直接把询问点平移到一开始的小迷宫里即可。

    3.可以沿着$(dx,dy)$这个向量达到某些左上角,那么先三分沿向量走的步数,把询问点平移到最近距离之后再判定。

    #include<cstdio>
    typedef long long ll;
    const int N=105,M=2000010,U=(1<<24)-1;
    int n,m,_,flag,dx,dy,i,j,x,y,h=1,t,q[M][2];char a[N][N];
    struct E{int x,y;E*nxt;}*g[U+1],pool[M],*cur=pool,*p;
    inline void read(int&a){
      char c;bool f=0;a=0;
      while(!((((c=getchar())>='0')&&(c<='9'))||(c=='-')));
      if(c!='-')a=c-'0';else f=1;
      while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';
      if(f)a=-a;
    }
    inline void ins(int x,int y){
      int u=((x<<9)^y)&U;
      p=cur++;p->x=x;p->y=y;p->nxt=g[u];g[u]=p;
    }
    inline bool ask(int x,int y){
      for(p=g[((x<<9)^y)&U];p;p=p->nxt)if(p->x==x&&p->y==y)return 1;
      return 0;
    }
    inline int pos(int x,int n){return (x%n+n)%n;}
    inline void ext(int x,int y){
      if(t==M-1)return;
      if(!a[pos(x,n)][pos(y,m)])return;
      if(ask(x,y))return;
      q[++t][0]=x;q[t][1]=y;ins(x,y);
    }
    inline ll abs(ll x){return x>0?x:-x;}
    inline ll dis(int x,int y,ll k){return abs(k*dx+x)+abs(k*dy+y);}
    inline bool query(int x,int y){
      if(t<M-1)return ask(x,y);
      if(flag)return ask(pos(x,n),pos(y,m));
      ll l=-1000000000,r=1000000000;
      while(l+5<r){
        ll len=(r-l)/3,m1=l+len,m2=r-len;
        if(dis(x,y,m1)<dis(x,y,m2))r=m2;else l=m1;
      }
      for(;l<=r;l++)if(dis(x,y,l)<=M)if(ask(l*dx+x,l*dy+y))return 1;
      return 0;
    }
    int main(){
      read(n),read(m);
      for(i=0;i<n;i++)for(scanf("%s",a[i]),j=0;j<m;j++)a[i][j]=a[i][j]=='.';
      ext(0,0);
      while(h<=t){
        x=q[h][0];y=q[h++][1];
        ext(x-1,y);
        ext(x+1,y);
        ext(x,y-1);
        ext(x,y+1);
      }
      if(t==M-1){
        if(ask(n,0)&&ask(0,m))flag=1;else for(i=2;i<=t;i++){
          x=q[i][0],y=q[i][1];
          if(x%n||y%m)continue;
          dx=x,dy=y;
          break;
        }
      }
      read(_);
      while(_--)read(x),read(y),puts(query(x,y)?"yes":"no");
      return 0;
    }
    

      

  • 相关阅读:
    KMP算法小结
    算法二叉搜索树之AVL树
    算法导论之红黑树的学习
    算法导论小结(一)
    感悟或摘抄
    js中神奇的东西
    简单了解webservice
    用<![CDATA[]]>将xml转义为 纯文本
    简单了解soap协议
    java写webservice接口
  • 原文地址:https://www.cnblogs.com/clrs97/p/6547319.html
Copyright © 2011-2022 走看看