zoukankan      html  css  js  c++  java
  • bzoj 2144 跳跳棋

    题目大意:

    棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z 棋子是没有区别的

    跳动的规则很简单,任意选一颗棋子,对一颗中轴棋子跳动 跳动后两颗棋子距离不变 一次只允许跳过1颗棋子

    思路:

    每个状态可以向三个状态转移 中间的向两边和两边中靠近中间的那一个向中间跳

    因此状态就可以构成一颗树 我们可以查找两个状态在树上的lca

    查找lca可以加速 处理出所有祖先

    先把两个状态放到同一深度

    然后二分 判断

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstdlib>
     5 #include<cstring>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #define inf 2139062143
    10 #define ll long long
    11 #define MAXN 2001000
    12 using namespace std;
    13 inline int read()
    14 {
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    18     return x*f;
    19 }
    20 int l1,l2,res;
    21 struct node
    22 {
    23     int x,y,z;
    24     bool operator == (const node &t) const
    25     {
    26         return x==t.x&&y==t.y&&z==t.z;
    27     }
    28     bool operator != (const node &t) const
    29     {
    30         return x!=t.x||y!=t.y||z!=t.z;
    31     }
    32 }a,b,f1,f2;
    33 node work(node t,int x)
    34 {
    35     for(int tmp=res=0,l,r;x;res+=tmp)
    36     {
    37         l=t.y-t.x,r=t.z-t.y;
    38         if(l==r) return t;
    39         if(l<r) tmp=min(x,(r-1)/l),t.x+=tmp*l,t.y+=tmp*l,x-=tmp;
    40         else tmp=min(x,(l-1)/r),t.y-=tmp*r,t.z-=tmp*r,x-=tmp;
    41     }
    42     return t;
    43 }
    44 int main()
    45 {
    46     a.x=read(),a.y=read(),a.z=read(),b.x=read(),b.y=read(),b.z=read();
    47     if(a.x>a.y) swap(a.x,a.y);if(a.y>a.z) swap(a.y,a.z);if(a.x>a.y) swap(a.x,a.y);
    48     if(b.x>b.y) swap(b.x,b.y);if(b.y>b.z) swap(b.y,b.z);if(b.x>b.y) swap(b.x,b.y);
    49     f1=work(a,inf),l1=res,f2=work(b,inf),l2=res;
    50     if(f1!=f2) {puts("NO");return 0;}
    51     if(l1<l2) {swap(a,b);swap(l1,l2);}
    52     a=work(a,l1-l2);int l=0,r=l2,mid,ans;
    53     while(r>=l)
    54     {
    55         mid=(l+r)>>1;
    56         if(work(a,mid)==work(b,mid)) ans=mid,r=mid-1;
    57         else l=mid+1;
    58     }
    59     printf("YES
    %d",l1-l2+(ans<<1));
    60 }
    View Code
  • 相关阅读:
    匿名对象
    封装性
    1 Django初探
    8 定制10MINs 3
    7 定制10MINs首页2
    5-1 练习css 总结
    6.定制10MINS首页1
    3-1 练习 HTML 总结
    5. css定位 居中
    4 CSS的20/80个知识点
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/9588050.html
Copyright © 2011-2022 走看看