dfs与bfs

描述

dfs
从某点出发,沿着一个方向往下试探,当找到目标位置,还需回溯,以便找到所有路径,再比较
最短的路径,比较盲目,效率不高, 使用了栈
bfs
将队首结点可拓展的点入队,如果没有可拓展的点,将队首结点出队,重复以上步骤,
直到到达目标位置或者队列为空,得到路径一定是最短的, 使用了队列;

dfs代码

一维dfs

#include<cstdio>
#include<iostream>
using namespace std;
int a[10], book[10], to = 0;//装数, 标记
void dfs(int step)//表示站在第几个盒子面前
{
    if(step == 9 + 1)//如果站在第十个盒子面前,那么前九个盒子已经放好扑克牌了
    {
        if(a[1]*100 + a[2]*10 + a[3] +a[4] *100+ a[5]*10 + a[6] == a[7]*100 + a[8]*10 + a[9])
        {//相关判断条件, 满足要求就打印这个解
            to++;
            printf("%d%d%d + %d%d%d = %d%d%d\n", a[1], a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
        }
        return;//重要-----返回之前的一步
    }
    
    for(int i =1;i<=9;i++)// 现在是站在第step个盒子面前, 按照1.2.3....9的顺序一一尝试
    {
        if(book[i]==0)//判断是否被标记使用过, 为0表示还没有使用过
        {
            a[step] = i;//将i放入第step个盒子中
            book[i] = 1;//标记已经使用过
            dfs(step + 1);//继续下一步
            book[i] = 0;//重要-----要将刚才尝试的收回, 才能进行下一步
        }
    }
}
int main()
{
    dfs(1);//站在第一个盒子前
    printf("总次数=%d\n", to/2);//有重复的
    return 0;
}

二维dfs

#include<cstdio>//最短路径
#include<iostream>
using namespace std;//1为障碍物
int n, m,a[100][100],book[100][100], d[4][2] = {1,0,0,1,-1,0,0,-1};
int sx , sy , step = 0, ex, ey, mi=9999;
void dfs(int sx, int sy, int step)
{
    if(sx==ex && sy ==ey)//等于终点了
    {
        if(step<mi)//找到最短路径
        mi = step;
        return;//返回上一步
    }
    for(int i=0;i<4;i++)
        {
            int tx = sx + d[i][1];//移动位置
            int ty = sy + d[i][0];
            if(tx < 1|| tx > n || ty <1 || ty >m)//越界了跳过
                continue;
            if(a[tx][ty]==0 && book[tx][ty] == 0)//如果不是障碍物,且没有标记过
            {
                book[tx][ty] = 1;//标记走过
                dfs(tx, ty, step + 1);//开始尝试下一个点, 步数也增加
                book[tx][ty] = 0;//尝试结束, 取消标记
            }
        }
    return;
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];

    cin>>sx>>sy>>ex>>ey;//起点 终点
    dfs(sx, sy, step);
    cout<<"step = "<<mi<<endl;
    return 0;
}

bfs代码

二维bfs-

#include <iostream>   /* 最短路径 */
#include <queue>
#include <map>
using namespace std;
int n,m,sx,sy,ex,ey;
int a[100][100], v[100][100], d[4][2] = {1,0,0,1,-1,0,0,-1};
struct po{
    int x, y, f,s;//可放入各种条件
};
void bfs()
{
    queue<po> r;//建队列
    r.push({sx,sy});//把当前位置放进去
    v[sx][sy] = 1;

    while(r.size())//队列不为空时
    {
        int x = r.front().x;//取出队顶元素
        int y = r.front().y;
        if(x == ex && y == ey)//判断是否符合条件
        {
            cout<<r.front().s;
            break;//符合跳出循环
        }

        for(int i=0;i<4;i++)
        {
            int tx = x + d[i][1];//继续移动位置
            int ty = y + d[i][0];
            if(tx < 1|| tx > n || ty < 1 || ty >m)//越界了跳过
                continue;
            if(a[tx][ty] == 0 && v[tx][ty] == 0)//如果没有走过, 且是空地
            {
                po temp;//临时变量存储位置,便于放入队列
                temp.x = tx;
                temp.y = ty;
                temp.s = r.front().s + 1;//位置移动,步数加1
                r.push(temp);
                v[tx][ty] = 1;//标记移动过的位置
            }
        }
        r.pop();//弹出位置
    }

}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>a[i][j];
    cin>>sx>>sy>>ex>>ey;
    bfs();
    return 0;
}

经典习题

全排列

#include <iostream>//全排列(有stl工具)
#include <vector>

using namespace std;

const int N = 15;
bool st[N];
int a[N];

vector<int> ve;
int v[N],n;

void dfs(int x)
{
    if(x > n)
    {
        for(vector<int>::iterator it=ve.begin();it != ve.end();it++) 
            cout<<*it;
        cout<<endl;
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(v[i]) continue;
        v[i]=1;
        
        ve.push_back(a[i]);
        dfs(x+1);
        v[i]=0;
        ve.pop_back();
    }

}

int main(void){
	scanf("%d", &n);
    for(int i=1;i<=n;i++)
        scanf("%d", &a[i]);
	dfs(1);
	return 0;
}

八皇后

#include<cstdio>
#include<iostream>
using namespace std;
int arr[14],v[3][28], ans = 0, n;
void dfs(int line){
    if(line > n){
        ans++;//几种方法
		for(int i = 1;i <= n;i++)
            	cout << arr[i] << " ";
        cout << endl; 
            return;
    }
    for(int i = 1;i <= n;i++){
        if((!v[0][i]) && (!v[1][line+i]) && (!v[2][line-i+n])){
            arr[line] = i;
            v[0][i] = 1; v[1][line+i] = 1; v[2][line-i+n] = 1;
            dfs(line+1);
            v[0][i] = 0; v[1][line+i] = 0; v[2][line-i+n] = 0;
        }
    }
}
int main(){
    cin >> n;
    dfs(1);
    if(ans == 0)
        cout<<"no solute!"<<endl;
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值