DFS搜索基础题,资深web前端开发

文章探讨了几个基于深度优先搜索(DFS)的编程问题,涉及数组操作、素数判断、网格遍历以及前端开发中的面试准备,展示了递归和回溯算法在解决实际问题中的应用。
摘要由CSDN通过智能技术生成

1 3 2

2 1 3

2 3 1

3 1 2

3 2 1

分析:这应该是我认为最基础的DFS题了,不需要太多想法,只需要按照DFS的理念一直往下搜,搜到底部,之后回溯

即可。DFS的一般理念设定一个数组visit[],作为判断当前是否已被遍历过。

代码如下

#include <stdio.h>

#include <string.h>

int a[1000],visit[1000],n;

int cunchu[10];

void dfs(int k )

{

int i;

if (k==n)//递归边界

{

for (i=0;i<k-1;i++) printf("%d ",cunchu[i]);

printf(“%d\n”,cunchu[k-1]);

return;

}

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

{

if (visit[i]==0)

{

visit[i]=1;

cunchu[k]=a[i];//存储每个位的数字

dfs(k+1);//搜索下一个数字

visit[i]=0;//回溯,搜索下一种情况

}

}

}

int main()

{

int s=0,i;

scanf(“%d”,&n);

memset(visit,0,sizeof(visit));//数组初始化

for (i=0;i<n;i++) a[i]=i+1;

dfs(0);

return 0;

}:

思考:这个题的数字限定在1~9;

那么(1)、加入0(0不能位于首位)。

(2)、加入重复数字(不准输出相同数字)。一步步加深难度,有兴趣可以做一下。

2、还是一个递归加上回溯的题目。

素数环(杭电hdu-1016)

时间限制:1000 ms  |  内存限制:65535 KB

描述

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。

为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。

输入

有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。

输出

如果存在满足题意叙述的素数环,从小到大输出。

否则输出No Answer。

样例输入

6

8

3

0

样例输出

Case 1:

1 4 3 2 5 6

1 6 5 2 3 4

Case 2:

1 2 3 8 5 6 7 4

1 2 5 8 3 4 7 6

1 4 7 6 5 8 3 2

1 6 7 4 3 8 5 2

Case 3:

No Answer

分析:这个题难度便比上一个题难度加大了不少,但是有一个易发现的规律:如果想相邻两个数和为素数,那么素数

环中必定是奇偶相隔,所以如果n是奇数,必定有两个奇数相邻的问题,如此便输出“No Answer”。当n==1时算作自

环,输出1。这个问题便简化了一大半了。

简化2;设立一个素数数组,把下标当数字,之后存储他是否是素数,0为素数,1为不是素数。

int prime[40]={1,1,0,0,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1,01,1,1,0,1,1};

简化3:依旧是设立一个visit[]数组,判断遍历与否。

代码如下:

#include

#include

int prime[40]={1,1,0,0,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,1,01,1,1,0,1,1};

int visit[21],ring[21];//ring[]存储环上的数字

void DFS(int k,int n)

{

int i;

if (k==n+1&&!prime[ring[1]+ring[n]])//递归边界

{

printf(“1”);//1每次都作为开头输出

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

printf(" %d",ring[i]);

printf(“\n”);

return;

}

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

{

if (!visit[i]&&!prime[i+ring[k-1]])//回溯加递归

{

visit[i]=1;

ring[k]=i;

DFS(k+1,n);

visit[i]=0;

}

}

}

int main()

{

int T,n;

T=1;

while(scanf(“%d”,&n),n)

{

printf(“Case %d:\n”,T++);

if(n==1)

{

printf(“1\n”);//特殊情况1

continue;

}

if(n&1)

{

printf(“No Answer\n”);//奇数

continue;

}

memset(visit,0,sizeof(visit));

visit[1]=ring[1]=1;

DFS(2,n);

}

return 0;

}

3、油田,八连快问题(来源http://poj.org/problem?id=1562)

Description

The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits.

GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides

the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to

determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two

pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and

may contain numerous pockets. Your job is to determine how many different oil deposits are contained

in a grid.

Input

The input contains one or more grids. Each grid begins with a line containing m and n, the number of

rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input;

otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not

counting the end-of-line characters). Each character corresponds to one plot, and is either `*',

representing the absence of oil, or `@', representing an oil pocket.

Output

are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100

pockets.

Sample Input

1 1

*

3 5

*@*@*

**@**

*@*@*

1 8

@@****@*

5 5

****@

*@@*@

*@**@

@@@*@

@@**@

0 0

Sample Output

0

1

2

2

分析:这个题也是DFS里的基础题,亦是设定一个visit[]数组,判断遍历与否。每次访问它便给他一个连通编号,最

后输出连通编号即可。

代码如下:

#include

#include

using namespace std;

const int maxn=1000;

int m,n,idx[maxn][maxn];

char pic[maxn][maxn];

void dfs(int r,int c,int id)

{

if (r<0||r>=m||c<0||c>=n) return;

if (idx[r][c]>0||pic[r][c]!=‘@’) return;

int dr,dc;

idx[r][c]=id;

for (dr=-1;dr<=1;dr++)

for (dc=-1;dc<=1;dc++)

if (dc!=0||dr!=0) dfs(r+dr,c+dc,id);

}

int main()

{

int i,j;

while (scanf(“%d%d”,&m,&n)==2&&m&&n)

{

int count=0;

for (i=0;i<m;i++) scanf(“%s”,pic[i]);

memset(idx,0,sizeof(idx));

for (i=0;i<m;i++)

for (j=0;j<n;j++)

if (idx[i][j]0&&pic[i][j]‘@’) dfs(i,j,++count);

printf(“%d\n”,count);

}

return 0;

}

4、细胞问题(来源http://acm.qust.edu.cn/problem.php?id=1230)

一矩形阵列由数字0到9组成,数字1到9为细胞数字,若沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形

阵列的细胞个数。

例如,

0234500067

1034560500

2045600671

0000000089,有4个细胞(细胞为加粗体区域)

输入

第一行是一个测试数据的个数T,表示将会有T组测试数据。

每组测试数据的第一行:两个数字M N (1<=M<=50 1<=N<80)表示该阵列有M行N列。

从第2行到第M+1行每行有连续的N个字符。

输出

与测试数据对应,刚好有T行,每行输出对应测试数据的细胞个数。

样例输入

1

4  10

0234500067

1034560500

2045600671

0000000089

样例输出

4

分析:此题与上一个题可以说是完全相似,只是每个位置的遍历方向减少了四个,只有上下左右,不多做赘述,直接

上代码。

代码如下:

#include

#include

int visit[51][81],m,n;

char a[51][81];

void dfs(int r,int c,int id)

{

if (r<0||c<0||r>=m||c>=n) return;

if (visit[r][c]>0||a[r][c]==‘0’)return;

visit[r][c]=id;

dfs(r+1,c,id);dfs(r-1,c,id);

dfs(r,c+1,id);dfs(r,c-1,id);

}

int main()

{

int cases,i,j;

scanf(“%d”,&cases);

getchar();

while (cases–)

{

int ans=0;

scanf(“%d%d”,&m,&n);

getchar();

memset(visit,0,sizeof(visit));

for (i=0;i<m;i++)

scanf(“%s”,a[i]);

for (i=0;i<m;i++)

for (j=0;j<n;j++)

{

if (visit[i][j]==0&&a[i][j]!=‘0’) dfs(i,j,++ans);

}

printf(“%d\n”,ans);

}

return 0;

}

5、拯救OIBH总部(来源于http://acm.qust.edu.cn/problem.php?id=1101)

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

核心竞争力,怎么才能提高呢?

成年人想要改变生活,逆转状态?那就开始学习吧~

万事开头难,但是程序员这一条路坚持几年后发展空间还是非常大的,一切重在坚持。

为了帮助大家更好更高效的准备面试,特别整理了《前端工程师面试手册》电子稿文件。

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

891.png)

前端面试题汇总

JavaScript

性能

linux

前端资料汇总

完整版PDF资料免费分享,只需你点赞支持,动动手指点击此处就可免费领取了

前端工程师岗位缺口一直很大,符合岗位要求的人越来越少,所以学习前端的小伙伴要注意了,一定要把技能学到扎实,做有含金量的项目,这样在找工作的时候无论遇到什么情况,问题都不会大。

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值