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));
}