2018/5/25:进与退,难与易,Dfs与Bfs

看到一条新闻:某大学宿舍8人7人考研成功,被封为“学霸宿舍”。


底下的评论可谓千姿百态:有赞赏羡慕的,有遗憾自己没考上的,也有说风凉话的。


其中有一个评论表示考研并不难。立刻遭到一群人的围攻:今年300w人考研,一群二战三战,研究生录取率只有9%balabalaba....考研好考?985热门专业你试试?balabalabala...


事实上,考研或许很难,很多新闻上——考研党在自习室深夜鏖战,在清晨等待图书馆开门,早出晚归,一天十几个小时的血汗,还要面临高达91%的失败几率,这一切都是对肉体和精神的严酷考验。

考研自习室层层叠叠的复习资料,走廊里断断续续的背书声,把大一时刚脱离高三的我吓坏了,我对着56米高的钟楼暗暗发誓:我就是保不了研,去工作,回家养猪,我也绝对不考研!


然而事实的变化总是快得超乎我的想象,现在我已经成了一个坚定的考研党预备党员。到底是什么促使我拥有现在的决心呢?可能是比考研更让我感到焦虑的那些东西吧。


在最初的时候,我很恐惧,为什么我要过那么苦的日子,高等数学,我碰都不想碰一下,然而当我鼓起勇气开始复习的时候,我反而好受了,边看视频边做题,一个月下来,我的笔记厚到我自己都不敢相信。我渐渐感觉考研并不需要穷兵黩武,考研本身就是一种学习,我为什么要对学习产生恐惧呢?对学习产生恐惧,我以后还能有什么作为?至少考研没我之前想的那么那么难了。


为什么之前我觉得考研那么那么难?或许其中存在一些偏差,正如新闻也好、网上经验交流帖也好,没人愿意把自己或自家学生的堕落一面展现出来,只会分享考研路上多么多么的坎坷,自己付出了多么多么多的努力,至于自己曾经一直或上课睡觉,或通宵追剧,或网吧夜游,或懒床躺尸这一堆确实发生过的破事,早就被考研路上的奋斗家忘到九霄云外了,就算记得,也没人愿意提了。我们周末早上十点在床上看到如此优秀努力的前辈都在考研路上折戟,再看看颓废如自己,羞愤欲跳床而死,还有何脸面作考研党的一员?正因如此,只有自家学长学姐的经验分享才有用的多,实际的多,可爱的多。


选择比努力重要,大家都是如此说道,但是没有经历过的人无法体会到这句话的沉重。难与易,是进还是退,这都是我们自己选择的,至于别人说难说易,除非他与自己的情况极相似,不然不可全信。


以上




正文开始:通过一个案例浅谈Dfs(深度优先搜索)和Bfs(广度优先搜索)


假设有一个n*m的迷宫,0表示通路,1表示有shit,我们如何在不踩到shit的情况下最快的走到目的地?


DFS:现在我们灵魂出窍,他沿着一条路走到底,没到目的地?转个弯,没到,转个弯,没到,转个弯。转完了?退一步,走到底,转弯,没到...可想而知,在一定时间内,这种方法一定能走完整个迷宫,好了,我们的灵魂知道了最短的路径,于是我们的肉体就可以行动了。而这种绕口令式的指令,就是递归。

人理解循环,神理解递归。但是人通过大量的练习,未必做不到神做的事。

于是有了以下code

#include

#include


int a[51][51],book[51][51],n,m,min=99999,p,q;//全局数组自动初始化为0 

int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//右,下,左,上 


void dfs(int x,int y,int step)

{

int tx,ty,k;

if(x==p&&y==q)//到达目的地,统计这种走法的总步数 

if(step

{

min=step;

return;

 } 

for(k=0;k<=3;k++)//四种走法 

{

tx=x+next[k][0];

ty=y+next[k][1];

if(tx>n||tx<1||ty<1||ty>m)//越界判断 

continue;

if(a[tx][ty]==0&&book[tx][ty]==0)//没走过且没shit 

{

book[tx][ty]=1;

dfs(tx,ty,step+1);

book[tx][ty]=0;

}

}

return;

}

int main(int argc, char *argv[]) {

int i,j,x,y;

printf("请输入几行几列:");

scanf("%d %d",&n,&m);

printf("请输入迷宫:\n"); 

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

scanf("%d",&a[i][j]);

printf("请输入出发点和目的地:");

scanf("%d %d %d %d",&x,&y,&p,&q);

dfs(x,y,0);

printf("最快到达终点需%d步\n",min); 

system("pause");

return 0;

}

编译,输入测试案例,正确运行

2018/5/25:进与退,难与易,Dfs与Bfs_第1张图片



BFS:依然是一个n*m的迷宫,0表示通路,1表示有shit,我们如何在不踩到shit的情况下最快的走到目的地?我们能不能换种方式?即我们多个灵魂同时出发,他们全都小心翼翼的一步一步往前,像固体溶解一样在迷宫里缓缓散开,像一滴掉在纸上的水珠缓缓扩张?

为了实现这种方式,我们需要用到队列。

#include

#include

int a[51][51],book[51][51],next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};


struct note//以每个点为结构体 

{

int x;

int y;

int s;

};

struct note que[2501];

int main(int argc, char *argv[]) {

int i,j,n,m,startx,starty,tx,ty,flag=0,p,q,k,head=1,tail=1,min;

printf("请输入几行几列:");

scanf("%d %d",&n,&m);

printf("请输入迷宫:\n"); 

for(i=1;i<=n;i++)

for(j=1;j<=m;j++)

scanf("%d",&a[i][j]);

printf("请输入出发点和目的地:");

scanf("%d %d %d %d",&startx,&starty,&p,&q);

que[tail].x=startx;

que[tail].y=starty;

que[tail++].s=0;

while(head

{

for(k=0;k<=3;k++)

{

tx=que[head].x+next[k][0];

ty=que[head].y+next[k][1];

if(tx<1||tx>n||ty<1||ty>m)

continue;

if(a[tx][ty]==0&&book[tx][ty]==0)

{

book[tx][ty]==1;

que[tail].x=tx;

que[tail].y=ty;

que[tail++].s=que[head].s+1;//往前迈一步,入队 

}

if(tx==p&&ty==q)//是否到达终点,到达则直接退出 

{

flag=1;

break;

}

 } 

if(flag==1)

{

break;

}

head++;

min=que[tail-1].s;//tail多走一步,需退回 

printf("最快到达终点需%d步\n",min); 

system("pause");

return 0;

}

测试结果

2018/5/25:进与退,难与易,Dfs与Bfs_第2张图片


以上

你可能感兴趣的:(c语言,算法)