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

    其实这道题并不是很难,但是确实不太好想啊。。。

    题目大意:

    跳跳棋是在一条数轴上进行的。棋子只能摆在整点上。每个点不能摆超过一个棋子。

    我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置。我们要通过最少的跳动把他们的位置移动成x,y,z。(棋子是没有区别的)

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

    写一个程序,首先判断是否可以完成任务。如果可以,输出最少需要的跳动次数。

    我们仔细的剖析一下题意:

    我们从题目中可知,一共只有三种移动方式:

    1.中间的棋子往左跳

    2.中间的棋子往右跳

    3.两边离中间近的棋子往中间跳(因为如果是远的棋子的话就会跳过两个了。。。)

    那么我们知道,如果不断进行第三步操作,最后一定会得到中间棋子到两边距离相等的情况,那么如果两种摆放方式经过这种迭代后,到中间距离相等,那么就代表他们是可以互相转换的,反之则不能。

    那么我们就可以判断是否可以完成任务了,而且我们知道棋子看的是相对位置,那么a   b        c,将a跳到bc中间就等于a,b同时向右移ab的差值,但是我们发现每一次减速度太慢,所以我们大可以将每一次移动差值步改为移动另一个差值%这个差值步,想一想正确性?

    那么,我们怎么计算需要多少步呢?由于我们知道每一次都有三种选择,那么如果我们从距离相等的情况开始拓展,那么就会有两种选择。也就是这些状态构成了一颗二叉树。

    那么我们所求的答案就是树上两点间距离啦!

    这个建一个树当然也可以,或者直接判断也行。。。

    关于时间复杂度,由于取模运算和gcd比较类似,所以忽略常数影响,应该是log级别的:logx(x是给出的最大距离差)

    最后,附上本题代码:

      1 #include<cstdio>
      2 #include<iostream>
      3 
      4 //Debug Yufenglin
      5 #define debugj printf("Running
    ");
      6 #define debugp1(x) printf("%d
    ",x);
      7 #define debugp2(x,y) printf("%d %d
    ",x,y);
      8 #define debugp3(x,y,z) printf("%d %d %d
    ",x,y,z);
      9 
     10 //Standfor Yufenglin
     11 #define LL long long
     12 #define LB long double
     13 #define reg register
     14 #define il inline
     15 #define inf 1e8
     16 #define maxn 1e5
     17 
     18 using namespace std;
     19 
     20 struct state
     21 {
     22     int x,y,z;
     23 };
     24 state pre,now,c1,c2,ct1,ct2;
     25 
     26 int abs(int x)
     27 {
     28     if(x<0) return -x;
     29     return x;
     30 }
     31 void merge(state &w)
     32 {
     33     if(w.x>w.y) swap(w.x,w.y);
     34     if(w.y>w.z) swap(w.y,w.z);
     35     if(w.x>w.y) swap(w.x,w.y);
     36 }
     37 bool judge(state a,state b)
     38 {
     39     if(a.x==b.x&&a.y==b.y&&a.z==b.z) return 1;
     40     return 0;
     41 }
     42 int find_father(state &w)
     43 {
     44     int step=0;
     45     while(w.x+w.z!=2*w.y)
     46     {
     47         int s1=w.y-w.x,s2=w.z-w.y;
     48         if(s1>s2)
     49         {
     50             int tep=s1/s2;
     51             if(s1%s2==0) tep--;
     52             w.y-=tep*s2;
     53             w.z-=tep*s2;
     54             merge(w);
     55             step+=tep;
     56         }
     57         else
     58         {
     59             int tep=s2/s1;
     60             if(s2%s1==0) tep--;
     61             w.x+=tep*s1;
     62             w.y+=tep*s1;
     63             merge(w);
     64             step+=tep;
     65         }
     66     }
     67     return step;
     68 }
     69 state update(state w,int mid)
     70 {
     71     merge(w);
     72     while(mid!=0)
     73     {
     74         int s1=w.y-w.x,s2=w.z-w.y;
     75         if(s1>s2)
     76         {
     77             int tep=s1/s2;
     78             if(s1%s2==0) tep--;
     79             tep=min(tep,mid);
     80             w.y-=tep*s2;
     81             w.z-=tep*s2;
     82             merge(w);
     83             mid-=tep;
     84         }
     85         else
     86         {
     87             int tep=s2/s1;
     88             if(s2%s1==0) tep--;
     89             tep=min(tep,mid);
     90             w.x+=tep*s1;
     91             w.y+=tep*s1;
     92             merge(w);
     93             mid-=tep;
     94         }
     95     }
     96     return w;
     97 }
     98 int main()
     99 {
    100     scanf("%d%d%d%d%d%d",&pre.x,&pre.y,&pre.z,&now.x,&now.y,&now.z);
    101     merge(pre),merge(now);
    102     c1=pre,c2=now;
    103     int temp1=find_father(pre),temp2=find_father(now);
    104     if(judge(pre,now)==0) printf("NO
    ");
    105     else
    106     {
    107         int dt=abs(temp1-temp2),l=0,r=min(temp1,temp2),ans;
    108         if(temp1<temp2) c2=update(c2,dt);
    109         else c1=update(c1,dt);
    110         while(l<=r)
    111         {
    112             int mid=(l+r)>>1;
    113             ct1=update(c1,mid);
    114             ct2=update(c2,mid);
    115             if(judge(ct1,ct2)==1) ans=mid,r=mid-1;
    116             else l=mid+1;
    117         }
    118         printf("YES
    %d
    ",dt+ans*2);
    119     }
    120     return 0;
    121 }
  • 相关阅读:
    解决CentOS java环境不生效的问题
    大数据学习 概念篇
    java实用技能 上传文件 等等
    ubuntu hadoop伪分布式部署
    list去重
    fastjson生成JSON字符串的时候出现$ref
    《Swift by Tutorials》学习笔记(第二章)
    《Swift by Tutorials》学习笔记(第一章)
    《JavaScript高级程序设计》学习笔记(第七章)
    《JavaScript高级程序设计》学习笔记(第五章)- 下
  • 原文地址:https://www.cnblogs.com/yufenglin/p/10629165.html
Copyright © 2011-2022 走看看