题解 P1588 【丢失的牛】

Push_Y

2019-06-08 21:44:54

题解

一个深搜的代码

这题开始我做了很多遍,有的MLE有的WA

应该说现在知道了容易犯错的点,给大家分享一下

首先,如果我们把牛固定,去移动FJ,那我们就会需要判断,坐标变为x*2的FJ有没有越界,这样速度就会减慢。

所以我们改变思路,固定FJ,移动牛,因为/2是不可能小于0的(无限趋向于0也不会小于0)。

把FJ和牛看成在一条数轴上

看代码↓

#pragma GCC ("Ofast")//在洛谷没用的优化,请省略
#include <bits/stdc++.h>
using namespace std;

int n,p,co,s,k;

/* n代表输入的组数
   p代表FJ的坐标
   co代表牛的初始坐标(因为牛会动)
   s代表dfs中的步数
   k代表所有s中的最小值,即最小步数
*/

void dfs(int c){//写函数dfs,c代表每次移动后牛的坐标
    if(c<p) {//如果移动后的牛已经到了FJ的左边,那直接做以下计算
        s+=p-c;
        if(s<k)k=s;   

        s-=p-c/2+1;//这个特别重要,记得减回去,我就是这个错没找出来做了很久

        return;
    }
    if(c%2==0){//考虑能够整除2的情况
        if(c/2>p){//牛x/2以后在FJ的右边那么移动是值得的
            s++;dfs(c/2);s--;
            return; 
        }
//接下来都是牛x/2在FJ的左边了
        if(p-c/2<c-p-1){//如果到左边以后值得
            s+=p-c/2+1;
            if(s<k)k=s;

         s-=p-c/2+1;//务必减回来

         return;
        }
        else {
            s+=c-p;
            if(s<k){
                k=s;
                return;
            }
        }
    }
    else {
        s++;dfs(c-1);s--;
        s++;dfs(c+1);s--;           
    }   
    return; 
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>p>>co;
        s=0;k=abs(co-p);//把k初始赋值为牛与FJ直接的距离
        dfs(co);
        cout<<k<<endl;
    }
}

便于大家调试,给出一组输入输出

输入:

2
2880 39798
4560 24257

输出:

398
1507