nflsoj 1351 抓住奶牛

发布时间 2023-08-05 09:05:15作者: typerxiaozhu

这题类似走迷宫,走迷宫是向四个方向进行拓展,而这道题好比是向三个方向拓展,分别是:\(x+1,x-1,x×2\)
在这里拓展的时候我写了一个函数 operation 来计算拓展后的坐标
这里判断坐标是否合法的时候我取了最大值的两倍加5,因为坐标不一定在 \(k\) 的左边,有可能超出去了再往回走,不过超出一次就行了,再超就没有意义了,那样往回走的步数更多
每个点记录两个东西,坐标以及是第几个拓展到的(时间)
注意:数组d是用来记录第几个拓展到的,所以初始化的时候是 d[n]=0;,把 \(n\) 当作是第0层往外拓展
最后返回 d[k] 就搞定了

#include <iostream>
#include <cstring>
using namespace std;
const int N = 100005;
typedef pair<int,int> PII; //当前位置及已经走了多少步
PII q[N];
int d[N];
int n,k;
int operation(int x,int i)
{
    if(i==0) return x+1;
    if(i==1) return x-1;
    if(i==2) return x*2;
}
int bfs()
{
    int hh=0,tt=0;
    q[0]={n,0};
    memset(d,-1,sizeof d);
    d[n]=0;
    while(hh<=tt)
    {
        PII t=q[hh++];
        for(int i=0;i<3;i++)
        {
            int x=operation(t.first,i);
            if(x>=0&&x<=200005&&d[x]==-1)
            {
                d[x]=d[t.first]+1;
                q[++tt]={x,t.second+1};
            }
        }
    }
    return d[k];
}
int main()
{
    cin>>n>>k;
    cout<<bfs();
    return 0;
}