笔记——dfs(模板)
盒子放数
题目:设共有n个盒子,1~n个数(不重复),问一共有多少种排法?(每个盒子放一个数)
#include <iostream>
using namespace std;
int a[10], book[10], n;
//类型必须为空,若需返回值,可定义一全局变量
void dfs(int step) {
if (step == n + 1) {
for (int i = 1; i <= n; i++)
cout << a[i] << ' ';
cout << endl;
return;//此行作用为返回上一步,固函数必须为void
}
for (int i = 1; i <= n; i++) {
if (book[i] == 0) {
a[step] = i;
book[i] = 1;
dfs(step + 1);
book[i] = 0;
}
}
return;
}
int main() {
cin >> n;
dfs(1);
return 0;
}
剪邮票
剪邮票
有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
请你计算,一共有多少种不同的剪取方法?
#include <iostream>
using namespace std;
int a[3][4], star[12], book[3][4], dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}}, count;
//a[][]:原框 star[]:起始点记录 book[][]:标记用过的点 dir[][]:移动 count 计数
int check(int x, int y) {
if (x >= 0 && x < 3 && y >= 0 && y < 4)
return 1;
else
return 0;
}
void dfs(int x, int y, int step) {
if (step == 5) {
count++;
return;
}
for (int i = 0; i < 4; i++) {
int tx, ty;
//移动(内项和,外项和)
tx = x + dir[i][1];
ty = y + dir[i][0];
if (check(tx, ty) && !book[tx][ty] && !star[a[tx][ty]]) {
//在棋盘内部 && 未使用 && 未作为起始点
book[tx][ty] = 1;
dfs(tx, ty, dep + 1);
book[tx][ty] = 0;
}
}
return;
}
int main() {
int n = 0;
//给框编号
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
a[i][j] = n++;
}
}
//传起始点
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
dfs(i, j, 0);
star[a[i][j]] = 1;//起始点标记
}
}
cout << count << endl;
return 0;
}