深度优先算法(DFS) 复习

概述

深度优先算法是一种很基本,常用的算法,是搜索算法中的一种。
它的实现主要用到了递归的思想,在一些树和图的遍历中,DFS会尽可能深地搜索树的分支,或搜索图的边,等到搜索条件不符合时,又回溯到上一节点,尝试其他走法。简单解释就是一条路走到黑,头很铁。在编程题目中一般用于解决迷宫类题目,棋盘类题目,如八皇后,跳马问题,连通问题,连通问题等。不过这种方法一般比较耗时,特别是在棋盘较大较复杂时,要较长时间才能算出结果,这时应该考虑广度优先(BFS)算法。

一般格式

void DFS(坐标,其他数据)
{
	if(条件)
	{
		相关操作;
		return//边界等条件
	}
	if(条件)
	{
		相关操作(标记);
		DFS(坐标,下一步)//递归	
		(回溯)
	}
}

题目1:八皇后

比较典型的回溯法题目,注意回溯条件的设置

#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
using std::string;
int chessmap[8][8],cnt=0;
void print(int m[8][8])
{
 for(int i=0;i<8;i++)
 {
  for(int j=0;j<8;j++)
  {
   if(m[i][j])std::cout<<"Q ";
   else std::cout<<"X ";
  }
  std::cout<<std::endl;
 }
 std::cout<<std::endl;
}
bool judge(int r,int c,int n)
{
 for(int i=0;i<c;i++)
 {
  if(chessmap[r][i]==1)return false;
 }
 for(int i=0;i<r;i++)
 {
  if(chessmap[i][c]==1)return false;
 }
 for(int i=r-1,j=c-1;i>=0,j>=0;i--,j--)
 {
  if(i<0||j<0)break;
  if(chessmap[i][j]==1)return false;
 }
 for(int i=r-1,j=c+1;i>=0,j<n;i--,j++)
 {
  if(i<0||j<0||j>=n)
   break;
  if(chessmap[i][j]==1)
   return false;
 }
 return true;
}
void queens(int n,int row)
{
 if(row==n)
 {
     print(chessmap);
     cnt++;
     /*memset(chessmap[row-1],0,sizeof(chessmap[row-1]));*/
 }
 else
 {
  for(int col=0;col<n;col++)
  {
   if(judge(row,col,n)==true)
   {
    chessmap[row][col]=1;
    queens(n,row+1);
    memset(chessmap[row],0,sizeof(chessmap[row]));
   }
  /* else
   {
    if(col==n-1)
    {
     memset(chessmap[row-1],0,sizeof(chessmap[row-1]));
    }
   }*/
  }
 }
}
int main()
{
 memset(chessmap,0,sizeof(chessmap));
 queens(8,0);
 std::cout<<cnt;
 return 0;
}

题目2:油田连通问题

用一个count来作标记,每多一个连通量count+1,最后输出count就行了。
比较无脑,照着格式套条件就行

#include<iostream>
#include<string.h>
#include<string>
using std::string;
const int maxn=100+5;
char oilmap[maxn][maxn];
int m,n,scan[maxn][maxn];
void DFS(int row,int col,int idx)
{
if(row<0||row>=m||col>=n||col<0)return;//judge edge
if(oilmap[row][col]!='@'||scan[row][col]>0)return;//judge if visited
scan[row][col]=idx;
for(int i=-1;i<=1;i++)
{
 for(int j=-1;j<=1;j++)
 {
  if(i!=0||j!=0)DFS(row+i,col+j,idx);//recursion 
 } 
} 
}
int main()
{
int count=0;
std::cin>>m>>n;
memset(scan,0,sizeof(scan));//clear
for(int i=0;i<m;i++)
{
  std::cin>>oilmap[i];
}
for(int i=0;i<m;i++)
{
 for(int j=0;j<n;j++)
 {
  if(scan[i][j]==0&&oilmap[i][j]=='@')
   DFS(i,j,++count);//recursion
 }
}
std::cout<<count<<std::endl;
return 0;
}

今天跟高中同学玩去了,只做了一点题,比较佛,明天认真更新>_<

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值