DFS+BFS

DFS

N个整数选择K个数

输出01序列-模板

#include <iostream>
#include <vector>

using namespace std;
vector<char> temp;
vector<vector<char>> result;

void DFS(int n) {
    if (temp.size() == n) { // 基线,完成一种情况的选择,加入result
        result.push_back(temp);
        return;
    }

    temp.push_back('0'); //第一种情况
    DFS(n);
    temp.pop_back(); // 回退
    
    temp.push_back('1'); // 第二种情况
    DFS(n);
    temp.pop_back(); // 回退

    return;
}

int main() {
    int n;
    scanf("%d", &n);

    DFS(n);

    for (int i = 0; i < result.size(); i++) {
        for (int j = 0; j < result[0].size(); j++) {
            printf("%c", result[i][j]);
        }
        printf("\n");
    }
}

子集🥰

  • 按子集顺序大小输出
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

vector<vector<int> > result;
vector<int> temp;
int n;

void DFS(int idx) {
    if (idx == n + 1) { // 基线,有时候在这里进行一些结果的处理
        result.push_back(temp);
        return;
    }
    temp.push_back(idx); // 选
    DFS(idx + 1);
    temp.pop_back(); // 不选
    DFS(idx + 1);
}

bool cmp(vector<int> &a, vector<int> &b) { // 按照子集大小排序
    if (a.size() != b.size()) {
        return a.size() < b.size();
    } else {
        return a < b;
    }
}

int main() {
    scanf("%d", &n);
    DFS(1);
    sort(result.begin(), result.end(), cmp);
    for (int i = 0; i < result.size(); i++) {
        for (int j = 0; j < result[i].size(); j++) {
            printf("%d", result[i][j]);
            if (j + 1 < result[i].size()) {
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}

全排列

  • use数组的使用
void DFS(int idx) {
    if (idx == n + 1) {
        result.push_back(temp);
        return;
    }
    for (int i = 1; i <= n; i++) {
        if (!used[i]) {
            temp.push_back(i);
            used[i] = true;
            DFS(idx + 1);
            used[i] = false;
            temp.pop_back();
        }
    }
}

N皇后🥲

八皇后

#include <iostream>
#include <vector>
#define maxn 8

using namespace std;
bool isExistQueen[maxn] = {false}; // 该列是否有皇后
int columnIdxofQueen[maxn]; // 每一行的皇后的列的位置
bool isDiagonalValid = true;
int ans = 0;

// 一行一行地找
void DFS(int rowIdx) {
    if (rowIdx == maxn) {
        ans ++;
        return;
    }

    for (int j = 0; j < maxn; j++) {
        if (!isExistQueen[j]) {
            isDiagonalValid = true;
            for (int i = rowIdx-1; i >= 0; i--) {
                // 同一对角线元素(x1,y1),(x2,y2):x1-x2 == y1-y2
                if (abs(rowIdx - i) == abs(j - columnIdxofQueen[i])) {
                    isDiagonalValid = false;
                    break;
                }
            }

            if (isDiagonalValid) {
                columnIdxofQueen[rowIdx] = j;
                isExistQueen[j] = true;
                DFS(rowIdx+1);
                isExistQueen[j] = false;
            }
        }
    }
}

int main() {
    DFS(0);

    printf("%d", ans);
}

矩阵最大权值

矩阵最大权值

#include <iostream>

using namespace std;
int a[5][5];
bool isVisit[5][5] = {false};
int maxw = -2500;
// 上下左右偏移量
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
int n, m;

bool isValid(int rowIdx, int colIdx) {
    if (0 <= rowIdx && rowIdx < n && 0 <= colIdx && colIdx < m) {
        return !isVisit[rowIdx][colIdx];
    }

    return false;
}

// 当前要访问的节点
void DFS(int rowIdx, int colIdx, int weight) {
	// 在判断权值之前要把当前节点的权值也加上,或者调用的时候就加上(边界注意)
    if (rowIdx == n-1 && colIdx == m-1) {
        if (maxw < weight) maxw = weight;
        return;
    }

    isVisit[rowIdx][colIdx] = true;

    for (int i = 0; i < 4; i++) {
        if (isValid(rowIdx + dx[i], colIdx + dy[i])) {
            DFS(rowIdx + dx[i], colIdx + dy[i], weight + a[rowIdx+dx[i]][colIdx+dy[i]]);
        }
    }

    isVisit[rowIdx][colIdx] = false;
}

int main() {
    scanf("%d %d", &n, &m);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    DFS(0, 0, a[0][0]);

    printf("%d", maxw);
}

BFS

模板

void BFS(int s) {
	queue<int> q;
	q.push(s);
	while(!q.empty()) {
		取出队首元素top;
		访问队首元素top;
		将队首元素出队;
		将top的下一层结点中未曾入队的结点全入队,并设置为已入队;
	}
}

迷宫问题

#include <iostream>
#include <queue>
#include <utility>

using namespace std;
typedef pair<int, int> Position;
int n, m, step = 0;
int a[100][100];
bool isVisit[100][100] = {false};
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
bool flag = false;
queue<Position> q;

bool isValid(int row, int col) {
    return 0 <= row && row < n && 0 <= col && col < m && !isVisit[row][col] && !a[row][col];
}

int BFS() {
    q.push(Position(0, 0));
    isVisit[0][0] = true;

    int cnt, row, col;
    while (!q.empty()) {
        cnt = q.size();
        // 处理一层结点
        for (int i = 0; i < cnt; i++) { 
            Position p = q.front();
            row = p.first;
            col = p.second;
            q.pop();
            // 判断放在里面
            if (row == n - 1 && col == m - 1) {
                return step;
            }
            for (int j = 0; j < 4; j++) {
                if (isValid(row + dx[j], col + dy[j])) {
                    isVisit[row + dx[j]][col + dy[j]] = true;
                    q.push(Position(row + dx[j], col + dy[j]));
                }
            }
        }

        step ++;
    }

    return -1;
}

int main() {
    scanf("%d %d", &n, &m);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    int step = BFS();

    printf("%d", step);


}

迷宫最短路

权值相同的图中,BFS求出来的第一条路径一定是最短路

#include <iostream>
#include <queue>
#include <vector>

using namespace std;
typedef pair<int, int> Position;
int n, m;
int a[100][100];
int isVisit[100][100];
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
Position pre[100][100];
queue<Position> q;
vector<Position> v;

bool isValid(int row, int col) {
    return 0 <= row && row < n && 0 <= col && col < m && !isVisit[row][col] && !a[row][col];
}

void BFS() {
    q.push(Position(0, 0));
    isVisit[0][0] = true;
    pre[0][0] = Position(-1, -1);

    int cnt;
    while (!q.empty()) {
        cnt = q.size();
        for (int i = 0; i < cnt; i++) {
            Position p = q.front();
            q.pop();
            if (p.first == n - 1 && p.second == m - 1) {
                return;
            }
            for (int j = 0; j < 4; j++) {
                if (isValid(p.first + dx[j], p.second + dy[j])) {
                    q.push(Position(p.first + dx[j], p.second + dy[j]));
                    isVisit[p.first + dx[j]][p.second + dy[j]] = true;
                    pre[p.first + dx[j]][p.second + dy[j]] = p;
                }
            }
        }
    }
}

void printPath(Position p) {
    if (p == Position(-1, -1)) {
        return;
    }

    Position prePosition = pre[p.first][p.second];

    printPath(prePosition);
    printf("%d %d\n", p.first + 1, p.second + 1);
}

int main() {
    scanf("%d %d", &n, &m);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    BFS();

    printPath(Position(n-1, m-1));
}
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值