【HD 2717】Catch That Cow (BFS)

小结一下BFS模板

(后面有单独的bfs小结)

写 一下做BFS 的思路。因为这题比较简单,代码量相对较少,也容易理解一些 更容易总结出模板

1、

先定义有关变量,一般是一个边界值、一个初始值、一个标记数组、加上一个 数组(一个变量) pair<>类型 (两个变量,如 x,y 坐标类型) 或 struct 定义一个新的类(三个以上变量)

2.

按照题意先建立主函数,如果是迷宫类问题,读入的可以直接用一层for循环加 %s 字符串,如果用两层for循环加 %c 字符的话要记得加getchar()

3.

最好bfs不要定义成int型,容易出现BUG(都是泪)。结果传递的时候注意 边界判断的 if 的位置,一般在while( q.size() )循环里 for()循环外。也不排除在for里面。

4.

到了最关键的bfs函数部分(……),bfs是宽度/广度搜索的简称,所以和dfs比起来,它有限搜索所有子节点,再搜索孙节点,以此类推。
在运用的时候一般是 队列/优先队列 + 一个模拟用的for + 一个判断用的judge(可以写在里面)来构成(如果用优先队列的话要记得重构)。

5.

运用时:先用for模拟所有的可能,然后判断是否加入队列,如果不符合,就自动进入下一个队列元素的循环(循环开始时该元素在队列中已经删除)。
否则的话就把该元素加入队列,并把计数数组vis加一。

6.

直到找到了ed(结束值)或者队列为空,循环结束。
——————————————————————————————————————————————-——

Catch That Cow

Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 12305 Accepted Submission(s): 3823

Problem Description
Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

  • Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
  • Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input
Line 1: Two space-separated integers: N and K

Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input
5 17

Sample Output
4

HintThe fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

Source
USACO 2007 Open Silver

Recommend
teddy | We have carefully selected several similar problems for you: 2102 1372 1240 1072 1180

————————————————————————————————————————————————

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>

using namespace std;

const int MAX_N = 1e5+11;
int st,ed;
int vis[MAX_N*2];
int d[MAX_N*2];
/*


*/ 

void bfs(int x)
{
    int nx;
    vis[x] = 1;
    d[x] = 0;
    queue<int>q;
    q.push(x);

    while( q.size() )
    {
        int s=q.front();
        q.pop();

        for(int i=1; i<=3; i++ )
        {
            if( i == 1 )
            {
                nx = s+1;
            }
            else if( i == 2 )
            {
                nx = s-1;
            }
            else
            {
                nx = s*2;
            }
            if( !vis[nx] && nx<=MAX_N && nx>=0 )
            {   
                vis[nx] = 1; 
                q.push(nx);
                d[nx] = d[s]+1;               
            }
            if( nx == ed )
            {
                 printf("%d\n",d[nx]);
                 return;
            }
        }
    }
}


int main()
{
    while( ~scanf("%d%d",&st,&ed))
    {   
        memset(vis, 0, sizeof(vis));  //一定要用 memset 别老用for循环清零 一个是麻烦,第二是容易错 
        memset(d, 0, sizeof(d));
        if( st == ed )
        {
            printf("0\n");
            continue;
        }

        bfs(st);
    }
    return 0;
}


/*
下面附上白皮书上的通用迷宫模板(略典型,思想还是一样的)
已经加好了注释:

const int INF = 0x3f3f3f;  //没有到达的地方都是无穷大 
typedef pair<int,int> P;  //如果量多了可以改成类 
char maze[MAX_N][MAX_N+1];   // 存储字符 
int N,M;
int sx,sy;  //开始坐标 
int gx,gy;  //结束坐标 

int d[MAX_N][MAX_N];  //记录走的步数 
int dx[4] = {1,0,-1,0};  //上下左右行走的模拟 
int dy[4] = {0,1,0,-1};

int bfs(){
    queue<P>que;   
    for( int i=0; i<N; i++ )
        for( int j=0; j<M; j++ )
        d[i][j] = INF;   //没有到过的地方全部标记为无穷大 
    que.push( P(sx,sy) );  // 把开始坐标放入队列 
    d[sx][sy] = 0;       //并把该点的距离设置为0while( que.front() ){ //判断队列是否为空 
        p = que.front();  //把队列的第一个值给 p ; 
        que.pop();  // 移除 
        if(P.first == gy && P.second == gy)break;
        //如果是到了终点直接退出 
        for(int i=0; i<4; i++ ){
            int nx = P.first + dx[i];
            int ny = P.second + dy[i];
        //改变坐标如果可以走,那么把新的地址储存,然后距离加一 
            if( 0<=nx && nx<N && 0<=ny && ny<M && maze[nx][ny] != '#' && d[nx][ny] == INF){
                que.push(P(nx,ny));
                d[nx][ny] = d[P.first][P.second] + 1;
        }
      }

    }
}
void solve(){
    int res = bfs();
    printf("%d\n",res);
}
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值