poj 3278 Catch that cow(BFS 广搜)

越来越觉得理解过程和代码实现绝对是两个层次的东西了。。上次并查集都啃了很久。。

广度优先搜索(BFS),概念很简答明了,媛姐讲时“分身”的说法很形象。

在方格迷宫中,怎样在最短时间内找到出口,要走哪个路线。可以是一个小人,上下左右走,每走到一格,就是一个独立的小人,这样依次往下,有点类似同心圆的形状。走过的方格进行标记,直到找到,输出。

很简答吧...但代码实现起来就是各种问题了。有几个问题要解决:

1,本身的位置,和走后的位置怎么存

2,计步(时)

存位置这个问题,一定是要用数组的。和自然的就能想到用栈,队列。栈是FILO不太方便,就队列。比如,5进队列后出队列,变成temp:4,6,10,再分别进队列,出队列变啊变...N是最初的小人,每个temp就是新的小人,就这就实现了广搜。

计不和计时是一样的,因为每一部耗时相同,最先找到终点K的,时间也就最小,所以计一个就行。

代码还是媛姐的代码,无限仰慕。。。。不过媛姐说的好啊,,“理解万岁~~”  是吧是吧···


#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
int Q[300000];      //队列
int count[300000];  //计步(时) 
int sta[300000];    //标记状态  
int n,head,tail;  
void Enq(int x)    	//入列 
{  
    Q[head++] = x;  
}  
int Deq(void)  		//出列	 
{  
    return Q[tail++];  
}  
int Qempty()  		//判队列是否空 
{  
    if( head == tail)//头=尾 空  
        return 1;  		
    return 0;  
}  
int main(void)  
{  
    int N,K,temp;  
    while(scanf("%d%d",&N,&K)!=EOF)  //5 17  
    {  
        head = 0;  
        tail = 0;  
        memset(count,0,sizeof(count));  
        memset(Q,0,sizeof(Q));  
        memset(sta,0,sizeof(sta));  
        Enq(N);              //N进队列 
        sta[N] = 1;          //已搜过的标记 
        while( !Qempty() )   //若非空 
        {  
            N = Deq();       //N出队列,FIFO 
            if( N == K)  
            {  
                printf("%d\n",count[N]);       //找到终点,输出步数
                break;  
            }  
            temp = N + 1;                          //+1小人
            if( temp<=100000 && sta[temp] == 0)    //若未走过且不超界
            {   
                sta[temp] = 1;                     //走,并且标记已走  
                count[temp] = count[N] + 1;        //步数+1
                Enq(temp);                         //小人入队列,出队新小人儿~~~
            }  
            temp = N - 1;  
            if( temp>=0 && sta[temp] == 0)  
            {  
                sta[temp] = 1;  
                count[temp] = count[N] + 1;  
                Enq(temp);  
            }  
            temp = N * 2;  
            if( temp<=100000 && sta[temp] == 0)  
            {  
                sta[temp] = 1;  
                count[temp] = count[N] + 1;  
                Enq(temp);  
            }          
        }  
    }  
  system("pause");  
return 0;  
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值