越来越觉得理解过程和代码实现绝对是两个层次的东西了。。上次并查集都啃了很久。。
广度优先搜索(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;
}