算法学习 深度优先搜索 DFS

算法学习 深度优先搜索 DFS,第1张

深度优先搜索就是一条路走到底的搜索,只要还能往下走就继续向下,直到不能再走或者都走过了就返回或退出。


来道简单的搜索题练一下:

题目取自洛谷 P1135 奇怪的电梯

#include
using namespace std;
int n, a, b;
int bj[205];
int arr[205];
int ans = 21474836;
void dfs(int begin, int end,int x) {
    //begin表示当前层数,end是要到达的层数,x是按键次数
    if (begin == end) {
        //如果当前层数就是要到达的层数,更新按键次数的最小值并返回
        ans = min(ans, x);
        return;
    }
    //剪枝,如果按键次数比最小的按键次数大了,这个答案就是错误的,返回
    if (x > ans) {
        return;
    }
    //标记当前层数到达过
    bj[begin] = 1;
    //如果当前层向上向下走楼层上的数字没有越界和将到达的那一层之前没有到达过就前往那一层
    if (begin - arr[begin] > 0&&bj[begin - arr[begin]]==0) {
        dfs(begin - arr[begin], end, x + 1);
    }
    if (begin + arr[begin] <= n&&bj[begin + arr[begin]]==0) {
        dfs(begin + arr[begin], end, x + 1);
    }
    //复原
    bj[begin] = 0;
}
int main() {
    //输入数据
    cin >> n >> a >> b;
    for (int i = 1; i <= n; i++) {
        cin >> arr[i];
    }
    //开始搜索
    dfs(a, b, 0);
    //如果搜完了ans还是和初始值一样就是不能到达,返回-1
    ans =ans==21474836 ? -1 : ans;
    cout << ans;
    return 0;
}

P1219 [USACO1.5]八皇后 Checker Challenge

这题和上一题差不多,只不过搜索的范围变成二维了,大概思路都是搜索到这个位置,标记已走过的位置和不能走的位置,直到不能再走了就更新答案并返回

#include
using namespace std;
int n;
int arr[14][14];//棋盘
int c = 0;//排列的总数
int js[15];//记录每行皇后所在列
void dfs(int x) {
    //x为行数,到达n行时就可结束了
    if (x == n) {
        c++;
        //前3个答案输出位置
        if (c < 4) {
            for (int i = 0; i < n; i++) {
                cout << js[i] << " ";
            }
            cout << endl;
        }
        return;
    }

    for (int i = 0; i < n; i++) {
        //如果arr[x][i]这个位置可以摆放
        if (arr[x][i] == 0) {
            //记录此行的皇后就放在i列,因为题目下标从1开始,所以时i+1
            js[x] = i + 1;
            //这边是标记下面的行数不能摆放的位置,0表示可以摆放,其他的都是不能摆放
            for (int j = x + 1; j < n; j++) {
                if (arr[j][i] == 0) {
                    arr[j][i] = x+1;
                }
            }
            int k = 1;
            while (x + k < n && i + k < n) {
                if (arr[x + k][i + k] == 0) {
                    arr[x + k][i + k] = x+1;
                }
                k++;
            }
            k = 1;
            while (x + k < n && i - k >= 0) {
                if (arr[x + k][i - k] == 0) {
                    arr[x + k][i - k] = x+1;
                }
                k++;
            }
            //向下一行进军
            dfs(x + 1);
            //还原
            for (int j = x + 1; j < n; j++) {
                if (arr[j][i] == x+1) {
                    arr[j][i] = 0;
                }
            }
             k = 1;
            while (x + k < n && i + k < n) {
                if (arr[x + k][i + k] == x+1) {
                    arr[x + k][i + k] = 0;
                }
                k++;
            }
            k = 1;
            while (x + k < n && i - k >= 0) {
                if (arr[x + k][i - k] == x+1) {
                    arr[x + k][i - k] = 0;
                }
                k++;
            }
        }
   }
}
int main() {
    cin >> n;
    //第0行开始
    dfs(0);
    cout << c << endl;
    return 0;
}

 最后也是成功AC惹

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/634282.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-16
下一篇 2022-04-16

发表评论

登录后才能评论

评论列表(0条)

保存