zoukankan      html  css  js  c++  java
  • BZOJ2144: 跳跳棋

    求三个人从a,b,c这三个位置跳到x,y,z最少多少步。跳:任意选一颗棋子,对一颗中轴棋子跳动。跳动后两颗棋子距离不变。一次只允许跳过1颗棋子。 

    从它跳的性质出发,向内跳只有一种操作,而向外跳有两种。这就是说,每个状态可以找到一个唯一前趋,有两个后继。这是一棵二叉树!求两个状态的最短路就是求他们到lca的距离和!

    类似于lca,先看两个状态能跳到的最终状态是否相同,在这个过程中记下两个状态的深度。然后让深度大的先跳,跳到两个状态深度一样后,二分答案让两个一起跳。

    问题是怎么快速地跳指定步数,记中间那个人和左右的间距为l和r,如果l小,那左边人往里跳一步,就会:l->l,r->r-l,更相减损,最后变成l,r%l,这r/l步可以很快跳。所以把r/l和指定步数x取个min让间隔小的那边的人跳就好了。

      1 #include<stdio.h>
      2 #include<string.h>
      3 #include<stdlib.h>
      4 #include<algorithm>
      5 //#include<iostream>
      6 using namespace std;
      7  
      8 int a,b,c,x,y,z;
      9 int ra,rb,rc,rx,ry,rz;
     10 void play(int a,int b,int c,int &ra,int &rb,int &rc,int &dep)
     11 {
     12 //  cout<<a<<' '<<b<<' '<<c<<endl;
     13     int l=b-a,r=c-b;
     14     if (l==r) {ra=a;rb=b;rc=c;return;}
     15     if (l<r)
     16     {
     17         if (!(r%l)) play(c-l-l,c-l,c,ra,rb,rc,dep),dep+=r/l-1;
     18         else play(c-r%l-l,c-r%l,c,ra,rb,rc,dep),dep+=r/l;
     19     }
     20     else
     21     {
     22         if (!(l%r)) play(a,a+r,a+r+r,ra,rb,rc,dep),dep+=l/r-1;
     23         else play(a,a+l%r,a+l%r+r,ra,rb,rc,dep),dep+=l/r;
     24     }
     25 }
     26 int ccc(int a,int b,int c)
     27 {
     28     int l=b-a,r=c-b;
     29     if (l<r)
     30     {
     31         if (!(r%l)) return r/l-1;
     32         else return r/l;
     33     }
     34     else
     35     {
     36         if (!(l%r)) return l/r-1;
     37         else return l/r;
     38     }
     39 }
     40 void jump(int &a,int &b,int &c,int x)
     41 {
     42     if (a==b || b==c) return;
     43     int l=b-a,r=c-b;
     44     if (l<r)
     45     {
     46         a+=x*l;
     47         b+=x*l;
     48     }
     49     else
     50     {
     51         c-=x*r;
     52         b-=x*r;
     53     }
     54 }
     55 //LL mul(LL a,LL b) {return a*b-(LL)((double)a/p*b)*p;}
     56 void Jump(int &a,int &b,int &c,int x)
     57 {
     58     for (;x;)
     59     {
     60         int tmp=min(x,ccc(a,b,c));
     61         jump(a,b,c,tmp);
     62         x-=tmp;
     63     }
     64 }
     65 bool check(int num)
     66 {
     67     int ta=a,tb=b,tc=c,tx=x,ty=y,tz=z;
     68 //  cout<<ta<<' '<<tb<<' '<<tc<<' '<<tx<<' '<<ty<<' '<<tz<<endl;
     69     Jump(ta,tb,tc,num);Jump(tx,ty,tz,num);//cout<<"->
    ";
     70 //  cout<<ta<<' '<<tb<<' '<<tc<<' '<<tx<<' '<<ty<<' '<<tz<<endl;
     71     return ta==tx && tb==ty && tc==tz;
     72 }
     73 void sos(int &a,int &b,int &c)
     74 {
     75     if (a>b) {int t=a;a=b;b=t;}
     76     if (a>c) {int t=a;a=c;c=t;}
     77     if (b>c) {int t=b;b=c;c=t;}
     78 }
     79 int main()
     80 {
     81     scanf("%d%d%d%d%d%d",&a,&b,&c,&x,&y,&z);
     82     sos(a,b,c);sos(x,y,z);
     83     int dep=0,ddd=0;
     84     play(a,b,c,ra,rb,rc,dep);play(x,y,z,rx,ry,rz,ddd);
     85 //  cout<<ra<<' '<<rb<<' '<<rc<<endl;
     86 //  cout<<rx<<' '<<ry<<' '<<rz<<endl;
     87 //  cout<<dep<<' '<<ddd<<endl;
     88     if (ra!=rx || rb!=ry || rc!=rz) puts("NO");
     89     else
     90     {
     91         puts("YES");
     92         if (dep<ddd) {swap(a,x);swap(b,y);swap(c,z);swap(dep,ddd);}
     93         int ans=0;
     94 //      cout<<a<<' '<<b<<' '<<c<<' '<<x<<' '<<y<<' '<<z<<endl;
     95         while (dep>ddd) {int tmp=min(dep-ddd,ccc(a,b,c));ans+=tmp;jump(a,b,c,tmp);dep-=tmp;}
     96 //      cout<<a<<' '<<b<<' '<<c<<' '<<x<<' '<<y<<' '<<z<<' '<<ans<<endl;}
     97         int L=0,R=ddd;
     98         while (L<R)
     99         {
    100             const int mid=(L+R)>>1;
    101             if (check(mid)) R=mid;
    102             else L=mid+1;
    103         }
    104         printf("%d
    ",ans+L*2);
    105     }
    106     return 0;
    107 }
    108 
    View Code
  • 相关阅读:
    hdu5728 PowMod
    CF1156E Special Segments of Permutation
    CF1182E Product Oriented Recurrence
    CF1082E Increasing Frequency
    CF623B Array GCD
    CF1168B Good Triple
    CF1175E Minimal Segment Cover
    php 正则
    windows 下安装composer
    windows apache "The requested operation has failed" 启动失败
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7643824.html
Copyright © 2011-2022 走看看