深度搜索DFS!

好的,接下来就是本萌新的第一篇博客啦。
直接上深搜
深度优先搜索(Depth-First-Search),简称“深搜”(dfs),是我们蒟蒻们最基本的搜索操作之一。
简单地说,深搜就是递归。
下面是抄来的解释:
深度优先搜索用一个数组存放产生的所有状态。
(1) 把初始状态放入数组中,设为当前状态;
(2) 扩展当前的状态,产生一个新的状态放入数组中,同时把新产生的状态设为当前状态;
(3) 判断当前状态是否和前面的重复,如果重复则回到上一个状态,产生它的另一状态;
(4) 判断当前状态是否为目标状态,如果是目标,则找到一个解答,结束算法。
(5) 如果数组为空,说明无解。
如果你看不懂,哦,好的,你可以继续看下去了。(当然如果你看懂了,大佬我们可以做朋友嘛?)
下面是一个图解:
假如,我们需要从A走到G去,实线代表的是我们可以走的路。
那么我们可以怎么走?

这种情况下,我们就只能从A>B>C>D>E>F>G这一条路去走,这没有多余方法,所以很简单。

但是这种情况我们就可以有多种选择从A走出。而我们又不知道该怎么走才能到达G点,那么我们选择一直走我们没走过的路,这样就有可能到达G。

比如,我们可以从A到达B,C,D三个点,这是我们选择E点。
当我们从A走到E后,又可以到B,C,D,F四个点,于是我们走到B点。
当我们到达B过后,发现有三条路,分别指向A,C,E三点。
因为我们不走回头路!所以只能走到C点。
当我们走到C过后,有通往B,E,G的三个点的路,我们就可以直接走到G点了。

由此看来这种“不走之前走过的老路”的方法是寻找一条路一直走到终点的。
虽然这种方式可能“绕远路”,但当我们只求到到达目标“不求最快”并且可以“闲心散步”时,这不错的选择。
(一路头铁肝到底!!!!!)
这就是深搜哦!
下面是深搜思路:
1.把所有点标记为“未走过”;//把数组全标记为0或者其他
2.找到起点,终点并看看可以走到哪里;//准备循环
3.选择一节点并判断本节点是否走出地图;//
4.判断这一节点走过没啊;//3、4两步是判断走到该节点是否合法
5.如果没走过就走进该节点;//标记该节点
6.再寻找下一个节点;//深入下一层搜索
7.走到头了就可以回头了//得到返回这就可以回溯了

再附加一道深搜题目:(摘自洛谷 P1219 八皇后// 其实还是来自USACO的!)

P1219 八皇后
题目描述
检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。

上面的布局可以用序列2 4 6 1 3 5来描述,第i个数字表示在第i行的相应位置有一个棋子,如下:

行号 1 2 3 4 5 6

列号 2 4 6 1 3 5

这只是跳棋放置的一个解。请编一个程序找出所有跳棋放置的解。并把它们以上面的序列方法输出。解按字典顺序排列。请输出前3个解。最后一行是解的总个数。

//以下的话来自usaco官方,不代表洛谷观点
特别注意: 对于更大的N(棋盘大小N x N)你的程序应当改进得更有效。不要事先计算出所有解然后只输出(或是找到一个关于它的公式),这是作弊。如果你坚持作弊,那么你登陆USACO Training的帐号删除并且不能参加USACO的任何竞赛。我警告过你了!

输入格式
一个数字N (6 <= N <= 13) 表示棋盘是N x N大小的。

输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。

输入输出样例
输入 #1 
6

输出 #1
2 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4

说明/提示
题目翻译来自NOCOW。
USACO Training Section 1.5

下面是香香源码哦!
源代码:
#include<bits/stdc++.h>//万能头文件刚住;
using namespace std;//引用不解释;
int h[15],l[15],zx[30],yx[30],N,cnt;
//h==行,l==列,zx==左斜线,rx==右斜线,N是棋盘大小, cnt记录次数;
void dfs (int x)//深度搜索当然是dfs啦
{
 if (x>N)//当放满了棋盘的每一行当然就放完了!
 {
  ++cnt;
  if (cnt<=3)
  {
   for(int i=1;i<=N;i++)
    cout<<h[i]<<‘ ‘;//输出
   cout<<endl;//记得在循环外清理缓存
  }
 }
 else//没放完就滚下来继续刚啊
 for(int i=1;i<=N;i++)
  {
   if(l[i]||zx[x-i+N]||yx[i+x])
//如果这个格子的同列,同左斜,同右斜上有棋子(被标记为1)
    continue;//就 再尝试下一个格子 
   l[i]=zx[x-i+N]=yx[i+x]=1;//没有标记过就标记嘛
   h[x]=i;//存上
   dfs(x+1);//再搜索下一行
   l[i]=zx[x-i+N]=yx[i+x]=0; //溯源  
  }  
 }
 int main()//主函数 好短啊。。。。
 {
  cin>>N;
 dfs(1);//直接开始搜索第一排
 cout<<cnt;
 return 0; //OK收工
 }

好啦,本萌新新的第一篇博客就到这里啦!

原文地址:https://www.cnblogs.com/xrs-2019/p/11620914.html

时间: 2024-08-12 00:49:45

深度搜索DFS!的相关文章

迷宫(深度搜索dfs)

首先输入一个迷宫,用0,1表示,如:m行n列的迷宫 5 4 0 0 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 1 0表示通路,1表示障碍. 然后输入起始点的坐标和终止点的坐标,求从起点到终点最少的步数. 用dfs,代码如下: <span style="font-size:18px;">#include<stdio.h> int book[51][51],p[51][51]; int min=99999,endx,endy;//因为终点坐

Word Search(深度搜索DFS,参考)

Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be us

数据结构之 栈与队列--- 走迷宫(深度搜索dfs)

走迷宫 Time Limit: 1000MS Memory limit: 65536K 题目描述 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方向任意走一步,并且有些格子是不能走动,求从起点到终点经过每个格子至多一次的走法数. 输入 第一行一个整数T 表示有T 组测试数据.(T <= 110) 对于每组测试数据: 第一行两个整数n, m,表示迷宫有n * m 个格子.(1 <= n, m <= 6, (n, m) !=(1, 1)

DFS深度搜索的一般思想

对于无向图来说DFS深度搜索 递归思想 //深度优先搜索DFS的一般实现 void DFS(MGraph G,int i)//DFS递归思想 { int j; visited[i]=TRUE;//设置Node已经被访问 printf("%c",G.vexs[i]); for(j=0;j<numVertexes;j++)//对此Node跟Node2(j)遍历 如果arc[][]==1则表明当前DFS的Node与Node2(j)连通,且满足Node2未被访问的条件下 则对Node2进

题目--oil Deposits(油田) 基础DFS(深度搜索)

上一次基本了解了下BFS,这次又找了个基本的DFS题目来试试水,DFS举个例子来说就是 一种从树的最左端开始一直搜索到最底端,然后回到原端再搜索另一个位置到最底端,也就是称为深度搜索的DFS--depth first search,话不多说,直接上题了解: Description:某石油勘探公司正在按计划勘探地下油田资源,工作在一片长方形的地域中.他们首先将该地域划分为许多小正方形区域,然后使用探测设备分别探测每一块小正方形区域内是否有油.若在一块小正方形区域中探测到有油,则标记为’@’,否则标

[LeetCode] Sum Root to Leaf Numbers dfs,深度搜索

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number. An example is the root-to-leaf path 1->2->3 which represents the number 123. Find the total sum of all root-to-leaf numbers. For example, 1 / 2 3 T

[LeetCode] Convert Sorted List to Binary Search Tree DFS,深度搜索

Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. Hide Tags Depth-first Search Linked List 这题是将链表变成二叉树,比较麻烦的遍历过程,因为链表的限制,所以深度搜索的顺序恰巧是链表的顺序,通过设置好递归函数的参数,可以在深度搜索时候便可以遍历了. TreeNode * help_f(Lis

[LeetCode] Maximum Depth of Binary Tree dfs,深度搜索

Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. Hide Tags Tree Depth-first Search 简单的深度搜索 #include <iostream> using namespace std; /** *

创建二叉树 树的深度搜索 广度搜索

树的深度搜索 与树的前序遍历同理 根节点->左孩子->右孩子  树的广度搜索 与树的层次遍历同理 一层一层遍历内容 深度搜索 采用stack的适配器 先进后出原则  而广度搜索采用的queue适配器 先进先出原则 二者正好满足 搜索需求 简要代码如下: #include <iostream> #include <stack> #include <queue> #include <malloc.h> using namespace std; typ