zoukankan      html  css  js  c++  java
  • BZOJ2647 : [Neerc2011]Journey

    $|x|+|y|=max(x+y,x-y,-x+y,-x-y)$,设$f[i][j]$表示在$(0,0)$,朝向方向$j$,执行第$i$条指令后的信息:

    $cir$:是否陷入循环

    $d$:朝向

    $x,y$:坐标

    $v_0$:$max(x+y)$

    $v_1$:$max(x-y)$

    $v_2$:$max(-x+y)$

    $v_3$:$max(-x-y)$

    然后记忆化搜索,当陷入循环时不再执行后面的指令。

    用栈维护所有正在计算的状态,若发现循环,则计算循环的$x$和$y$之和,若为$0$则是循环,否则会走到无限远处。

    时间复杂度$O(n^3)$。

    #include<cstdio>
    #include<string>
    #include<iostream>
    #include<cstdlib>
    using namespace std;
    const int N=110,Base=100000000,MAXL=32;
    int n,i,j,a[N],q[N*4][2],in[N][4];string b[N][N];bool vis[N][4],cir[N][4];
    inline int max(int a,int b){return a>b?a:b;}
    struct Num{
      int a[MAXL],len,fu;
      void init(){len=1,fu=a[1]=0;}
      Num(){init();}
      bool iszero(){return len==1&&!a[1];}
      Num operator+(const Num&b){
        Num c;
        c.len=max(len,b.len)+2;
        int i;
        for(i=1;i<=c.len;i++)c.a[i]=0;
        if(fu==b.fu){
          for(i=1;i<=len;i++)c.a[i]=a[i];
          for(i=1;i<=b.len;i++)c.a[i]+=b.a[i];
          for(i=1;i<=c.len;i++)if(c.a[i]>=Base)c.a[i+1]++,c.a[i]-=Base;
          while(c.len>1&&!c.a[c.len])c.len--;
          c.fu=fu;
        }else{
          bool flag=0;
          if(len==b.len){
            for(i=len;i;i--)if(a[i]!=b.a[i]){
              if(a[i]>b.a[i])flag=1;
              break;
            }
          }else{
            if(len>b.len)flag=1;
          }
          if(flag){
            for(i=1;i<=len;i++)c.a[i]=a[i];
            for(i=1;i<=b.len;i++)c.a[i]-=b.a[i];
            for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;
            while(c.len>1&&!c.a[c.len])c.len--;
            c.fu=fu;
          }else{
            for(i=1;i<=b.len;i++)c.a[i]=b.a[i];
            for(i=1;i<=len;i++)c.a[i]-=a[i];
            for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;
            while(c.len>1&&!c.a[c.len])c.len--;
            c.fu=b.fu;
          }
        }
        if(c.iszero())c.init();
        return c;
      }
      void operator+=(const Num&b){*this=*this+b;}
      Num operator-(const Num&b){
        Num c;
        c.len=max(len,b.len)+2;
        int i;
        for(i=1;i<=c.len;i++)c.a[i]=0;
        if(fu!=b.fu){
          for(i=1;i<=len;i++)c.a[i]=a[i];
          for(i=1;i<=b.len;i++)c.a[i]+=b.a[i];
          for(i=1;i<=c.len;i++)if(c.a[i]>=Base)c.a[i+1]++,c.a[i]-=Base;
          while(c.len>1&&!c.a[c.len])c.len--;
          c.fu=fu;
        }else{
          bool flag=0;
          if(len==b.len){
            for(i=len;i;i--)if(a[i]!=b.a[i]){
              if(a[i]>b.a[i])flag=1;
              break;
            }
          }else{
            if(len>b.len)flag=1;
          }
          if(flag){
            for(i=1;i<=len;i++)c.a[i]=a[i];
            for(i=1;i<=b.len;i++)c.a[i]-=b.a[i];
            for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;
            while(c.len>1&&!c.a[c.len])c.len--;
            c.fu=fu;
          }else{
            for(i=1;i<=b.len;i++)c.a[i]=b.a[i];
            for(i=1;i<=len;i++)c.a[i]-=a[i];
            for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=Base;
            while(c.len>1&&!c.a[c.len])c.len--;
            c.fu=b.fu^1;
          }
        }
        if(c.iszero())c.init();
        return c;
      }
      void operator-=(const Num&b){*this=*this-b;}
      bool operator<(const Num&b){
        if(fu!=b.fu)return fu;
        if(fu){
          if(len!=b.len)return len>b.len;
          for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]>b.a[i];
        }else{
          if(len!=b.len)return len<b.len;
          for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]<b.a[i];
        }
        return 0;
      }
      void write(){
        if(fu)putchar('-');
        printf("%d",a[len]);
        for(int i=len-1;i;i--)printf("%08d",a[i]);
      }
      void set(int x){
        fu=0;
        if(x<0)x=-x,fu=1;
        len=1;
        a[1]=x;
      }
    }zero,one,x,y;
    inline void up(Num&a,const Num&b){if(a<b)a=b;}
    struct E{
      int d;Num x,y,v0,v1,v2,v3;
      void left(){d=(d+1)&3;}
      void right(){d=(d+3)&3;}
      void init(int _d){
        d=_d;
        x.set(0);
        y.set(0);
        v0.set(0);
        v1.set(0);
        v2.set(0);
        v3.set(0);
      }
      void go(){
        if(d==0)x+=one;
        if(d==1)y+=one;
        if(d==2)x-=one;
        if(d==3)y-=one;
        up(v0,x+y);
        up(v1,x-y);
        up(v2,y-x);
        up(v3,zero-x-y);
      }
      void merge(const E&b){
        d=b.d;
        up(v0,x+y+b.v0);
        up(v1,x-y+b.v1);
        up(v2,y-x+b.v2);
        up(v3,zero-x-y+b.v3);
        x+=b.x;
        y+=b.y;
      }
      void write(){
        up(v0,v1);
        up(v0,v2);
        up(v0,v3);
        v0.write();
      }
    }f[N][4];
    inline int cal(const string&s){
      int t=0;
      for(int i=1;i<s.size();i++)t=t*10+s[i]-'0';
      return t;
    }
    inline void check(int l,int r){
      for(x.set(0),y.set(0);l<=r;l++)x+=f[q[l][0]][q[l][1]].x,y+=f[q[l][0]][q[l][1]].y;
      if(x.iszero()&&y.iszero())return;
      puts("Infinity");
      exit(0);
    }
    void cal(int x,int y,int d){
      if(vis[x][y])return;
      vis[x][y]=1;
      q[in[x][y]=d][0]=x;
      q[d][1]=y;
      f[x][y].init(y);
      for(int i=0;i<a[x];i++){
        if(b[x][i]=="GO")f[x][y].go();
        else if(b[x][i]=="LEFT")f[x][y].left();
        else if(b[x][i]=="RIGHT")f[x][y].right();
        else{
          int A=cal(b[x][i]),B=f[x][y].d;
          if(in[A][B]){
            check(in[A][B],d);
            cir[x][y]=1;
          }else{
            cal(A,B,d+1);
            f[x][y].merge(f[A][B]);
            if(cir[A][B])cir[x][y]=1;
          }
          if(cir[x][y])break;
        }
      }
      in[x][y]=0;
    }
    int main(){
      zero.set(0);
      one.set(1);
      cin>>n;
      for(i=1;i<=n;i++){
        cin>>a[i];
        for(j=0;j<a[i];j++)cin>>b[i][j];
      }
      cal(1,0,1);
      f[1][0].write();
      return 0;
    }
    

      

  • 相关阅读:
    mysql压缩版安装
    网站还没加载完成时,显示正在加载的画面
    LESS基础教程
    用CSS编写多种常见的图形
    JavaScript的this
    JavaScript的闭包
    立即执行函数表达式(自执行函数)
    JavaScript的全局变量
    关于async function(){ let res = await } 详解
    mysql数据库的系统操作基本操作
  • 原文地址:https://www.cnblogs.com/clrs97/p/8537219.html
Copyright © 2011-2022 走看看