POJ3278:Catch That Cow——BFS

题目描述

Farmer John从n位置出发,去找k位置的牛,每一步需要花费1minute,每一步可选的方式如下:

  • 走到n+1
  • 走到n -1
  • 走到2*n

求FJ找到牛所需要的最短时间


搜索:初始状态经过一系列状态转变到达目标状态

状态空间:<位置,时间>

状态转换:<n+1,t+1>、<n-1,t+1>、<n*2,t+1>

初始状态:<n,0>

目标状态:<k,t>

搜索策略:BFS(广度优先搜索)、DFS(深度优先搜索)

BFS中一层一层地进行搜索,而每一层(相当于每走一步)所花时间就要+1,要求花费时间最小,因此使用BFS


算法思路

  1. 初始化visit数组
  2. 起始状态访问入队
  3. 取出队首状态,求其转换状态,并判断是否合法,访问入队
  4. 重复3,直到队列为空

注意:要判断新状态是否合法


#include<iostream>
#include<cstdio>
#include<queue>
#include<string.h>
using namespace std;

const int MAXN = 1E5 + 10;

struct Status{
    int pos;
    int time;
    Status(int p, int t): pos(p), time(t){}
};

bool visit[MAXN];


int BFS(int n, int k){
    queue<Status> q;
    q.push(Status(n, 0));              //压入初始状态
    visit[n] = true;                   //起点已访问
    int ans = 0;

    while(!q.empty()){
        Status current = q.front();
        q.pop();
        if(current.pos == k){           //查找成功
            ans = current.time;
            break;
        }

        for(int i = 0; i < 3; ++i){    //3种状态转换
            Status nextStatus = current;
            if(i == 0){                 
                nextStatus.pos -= 1;
            }
            else if(i == 1){
                nextStatus.pos += 1;
            }
            else{
                nextStatus.pos *= 2;
            }
            ++nextStatus.time;
            if(nextStatus.pos < 0 || nextStatus.pos > 1e5 || visit[nextStatus.pos]){
                continue;                   //新状态不合法
            }
            q.push(nextStatus);             //压入新状态
            visit[nextStatus.pos] = true;   //该结点已访问
        }
    }
    return ans;
}

int main(){
    int n, k;
    scanf("%d%d", &n, &k);
    memset(visit, false, sizeof(visit));
    printf("%d\n", BFS(n, k));
    return 0;
}
posted @ 2022-01-28 19:28  dctwan  阅读(34)  评论(0编辑  收藏  举报