深搜无剪枝等于暴力搜索
宽搜有最短路径的性质
八皇后问题
a[i] 表示 第i行的皇后放在第a[i]列上
b[i] 有true和false两种取值
- true:第i列可用
- false:第i列不可用
逐行放置皇后
对角线如何判断?(出现负数用map)
#include<bits/stdc++.h>
using namespace std;
#define int long long
// #define max(a,b) ((a)>(b))?a:b
// #define min(a,b) ((a)<(b))?a:b
#define pb push_back
vector<int> a(9,0);
vector<bool> b(9,true), c(30,true);
map<int, bool> mp;
int ans = 0; // 方案数
// n代表放置第几个皇后
void dfs(int n){
//八个皇后都已放好
if(n==9) {
ans++;
for (int i=1; i<=8; i++) {
cout << a[i] << ' ';
}
cout << '\n';
};
// 枚举放在每一列的情况
for (int i=1; i<=8; i++) {
// 可放
if (b[i] && c[n+i] && mp[n-i]) {
a[n] = i;
b[i] = c[n+i] = mp[n-i] = false;
// 放下一个
dfs(n+1);
// 深度搜索到头回溯
a[n] = 0;
b[i] = c[n+i] = mp[n-i] = true;
}
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
// 对角线判断可能出现负数,所以用map
for (int i=0; i<=30; i++) {
mp[i] = true;
mp[-i] = true;
}
dfs(1);
cout << ans;
return 0;
}
Triangle - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
#define int long long
// #define max(a,b) ((a)>(b))?a:b
// #define min(a,b) ((a)<(b))?a:b
#define pb push_back
int ans1 = 0, ans2 = 0;
vector<bool> b(5, true);
vector<int> c(4,0), a(5,0); // 存选出的木棒
// x 是 选第几个木棒
void dfs(int x) {
// 选木棒
if (x==4) {
// cout << c[1] << c[2] << c[3] << '\n';
// 一定要开新数组,否则排序会打乱c数组的顺序,影响回溯
vector<int> d = c;
sort(d.begin()+1, d.end());
if (d[1]+d[2]>d[3]) {
ans1 = 1;
}
else if (d[1]+d[2]==d[3]) ans2 = 1;
return;
}
for (int i=1; i<=4; i++) {
// i能选
if (b[i]) {
c[x] = a[i];
b[i] = false;
x++;
dfs(x);
x--;
b[i] = true;
c[x] = 0;
}
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
for (int i=1; i<=4; i++) {
cin >> a[i];
}
dfs(1);
if (ans1) cout << "TRIANGLE";
else if (ans2) cout << "SEGMENT";
else cout << "IMPOSSIBLE";
return 0;
}
Far Relative’s Birthday Cake - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
#define int long long
// #define max(a,b) ((a)>(b))?a:b
// #define min(a,b) ((a)<(b))?a:b
#define pb push_back
int n,i,j;
int ans = 0; // 幸福指数
char s[105][105]; //地图数组
vector<vector<bool>> vis(105,vector<bool>(105,true)); //访问数组
bool check(int x, int y) {
if (x == i && y <= n) return 1; //在同一行
if (x <= n && y == j) return 1; // 在同一列
return 0;
}
// 当前位置的横纵坐标x、y
void dfs(int x, int y) {
// x、y超过范围返回
if (!check(x,y)) return;
// 当前位置不是(i,j)且为'C'
if (s[x][y] == 'C' && (x!=i || y!=j)) {
// cout << i << j << x << y << '\n';
ans++;
}
// 继续搜索
dfs(x+1, y); // 下面一格
dfs(x, y+1); // 右面一格
// 无需回溯
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
cin >> s[i][j];
// 双重循环找'C', 找到就DFS。
for (i=1; i<=n; i++) {
for (j=1; j<=n; j++) {
// 搜索(i,j)以下和以右
if (s[i][j] == 'C') {
vis[i][j] = false; //防止和自身配对使得ans+1
dfs(i, j);
}
}
}
cout << ans;
return 0;
}
DZY Loves Chessboard - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
#include<bits/stdc++.h>
using namespace std;
#define int long long
// #define max(a,b) ((a)>(b))?a:b
// #define min(a,b) ((a)<(b))?a:b
#define pb push_back
int n,m,i,j;
char s[105][105]; //地图数组
vector<vector<bool>> vis(105,vector<bool>(105,true)); //访问数组
// 当前位置的横纵坐标x、y, i表示当前应该放哪种棋子
void dfs(int x, int y, int i) {
vis[x][y] = false; //访问过不会再访问
// cout << x << ' ' << y << '\n';
// x、y超过范围返回
if (x>n || y>m || x<1 || y<1) return;
// 当前位置不是(i,j)且为'C'
if (s[x][y] == '.') {
if (i==0) // 0放白
s[x][y] = 'W';
else // !0放黑
s[x][y] = 'B';
}
// 未访问到的点就继续搜索
if (vis[x+1][y]) dfs(x+1, y, !i); // 下面一格放!i
if (vis[x][y+1]) dfs(x, y+1, !i); // 右面一格放!i
if (vis[x-1][y]) dfs(x-1, y, !i); // 上面一格放!i
if (vis[x][y-1]) dfs(x, y-1, !i); // 左面一格放!i
// 无需回溯
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
cin >> s[i][j];
dfs(1,1,0);
for (int i=1; i<=n; i++) {
for (int j=1; j<=m; j++){
cout << s[i][j];
}
cout << '\n';
}
return 0;
}