zoukankan      html  css  js  c++  java
  • [洛谷P1852][题解]跳跳棋

    作为紫题却是一道巨大神的人类智慧题,由于智商不足所以看了题解……
    观察跳棋的性质,我们发现中间的棋子可以通过向两边跳扩张区间,两边的棋子最多有一个能通过向中间跳缩小区间,并且最后会缩成两边的棋子关于中间对称的形态。
    先解决判定无解的问题。由于一个区间向外可以扩张成两个,向内可以缩小成一个,我们利用缩小的唯一性,看两个状态不断缩小时是否有交集即可。
    然后最优解可以直接加一个二分。
    但是这样你发现会 T 飞,我们不能每次只跳一步。发现有些步数可以用取模优化掉,最终复杂度变成了辗转相除一样的东西,可以通过此题。

    如果你还是理解不了上面的过程,这里给出另一种理解方式:把扩张想象成儿子,缩小想象成父亲,这样就是一棵二叉树,答案就是树上路径的距离。

    int ans;
    struct Tri {
      int a,b,c;
      void S(){
        if(a>b)swap(a,b);
        if(a>c)swap(a,c);
        if(b>c)swap(b,c);
      }
    }A,B;
    bool operator == (Tri A,Tri B){
      return A.a==B.a&&A.b==B.b&&A.c==B.c;
    }
    il Tri Get(Tri _A,int &stp){//get final status
      Tri A=_A;A.S();
      while(A.b-A.a!=A.c-A.b){
        int lt=A.b-A.a,rt=A.c-A.b;
        if(lt<rt){//a jumps over b
          int q=rt/lt,r=rt%lt;
          if(!r)r=lt,q--;
          A.a+=rt-r,A.b+=rt-r,stp+=q;
        }else {//c jumps over b
          int q=lt/rt,r=lt%rt;
          if(!r)r=rt,q--;
          A.c-=lt-r,A.b-=lt-r,stp+=q;
        }
      }
      return A;
    }
    il Tri Check(Tri _A,int lmt){
      Tri A=_A;A.S();
      while(lmt>0){
        int lt=A.b-A.a,rt=A.c-A.b;
        if(lt<rt){//a jumps over b
          int q=rt/lt,r=rt%lt;
          if(!r)r=lt,q--;
          if(q>lmt)q=lmt;
          A.a+=q*lt,A.b+=q*lt,lmt-=q;
        }else {//c jumps over b
          int q=lt/rt,r=lt%rt;
          if(!r)r=rt,q--;
          if(q>lmt)q=lmt;
          A.c-=q*rt,A.b-=q*rt,lmt-=q;
        }
      }
      return A;
    }
    int main(){
      Read(A.a),Read(A.b),Read(A.c);
      Read(B.a),Read(B.b),Read(B.c);
      A.S(),B.S();
      int stpa=0,stpb=0;
      if(!(Get(A,stpa)==Get(B,stpb)))return puts("NO"),0;
      int d;
      if(stpa<stpb)d=stpb-stpa,B=Check(B,d);
      else d=stpa-stpb,A=Check(A,d);
      int l=0,r=min(stpa,stpb);
      while(l<=r){
        int m=nmid;Tri _A=Check(A,m),_B=Check(B,m);
        if(_A==_B)ans=m,r=m-1;
        else l=m+1;
      }
      cout<<"YES"<<endl<<ans+ans+d<<endl;
      KafuuChino HotoKokoa
    }
    
    内容来自_ajhfff_的博客(https://www.cnblogs.com/juruoajh/),未经允许,不得转载。
  • 相关阅读:
    C#-Linq-SelectMany
    C#-Linq-SelectMany
    DI是实现面向切面和面向抽象的前提
    java流程控制之Scanner(2)
    java流程控制之Scanner(1)
    java运算符之三目运算符
    java运算符之位运算
    java运算符之与或非
    java运算符之加减乘除
    java基础语法
  • 原文地址:https://www.cnblogs.com/juruoajh/p/14963173.html
Copyright © 2011-2022 走看看