1 条题解
-
0
八重循环
#include <bits/stdc++.h> using namespace std; // pos[i] 记录第 i 列的皇后出现在哪儿 int pos[10]; bool check() { for (int i = 1; i <= 8; i++) for (int j = 1; j < i; j++) { // 检查第 i 个皇后和第 j 个皇后是否冲突 //(pos[i], i), (pos[j], j) if (pos[i] == pos[j] || i == j || i + pos[i] == j + pos[j] || i - pos[i] == j - pos[j]) return false; } return true; } int main() { ios::sync_with_stdio(false); cin.tie(0); int tot = 0; for (pos[1] = 1; pos[1] <= 8; pos[1]++) for (pos[2] = 1; pos[2] <= 8; pos[2]++) for (pos[3] = 1; pos[3] <= 8; pos[3]++) for (pos[4] = 1; pos[4] <= 8; pos[4]++) for (pos[5] = 1; pos[5] <= 8; pos[5]++) for (pos[6] = 1; pos[6] <= 8; pos[6]++) for (pos[7] = 1; pos[7] <= 8; pos[7]++) for (pos[8] = 1; pos[8] <= 8; pos[8]++) { if (check()) { tot++; cout << "No. " << tot << "\n"; for (int i = 1; i <= 8; i++) { for (int j = 1; j <= 8; j++) if (pos[j] == i) cout << "1 "; else cout << "0 "; cout << "\n"; } } } return 0; }
基础搜索,每列随便放,最后再检查
#include <bits/stdc++.h> using namespace std; int n = 8, tot; // n 皇后,tot 种方案 // pos[i] 记录第 i 列的皇后出现在哪儿 int pos[10]; bool check() { for (int i = 1; i <= n; i++) for (int j = 1; j < i; j++) { // 检查第 i 个皇后和第 j 个皇后是否冲突 //(pos[i], i), (pos[j], j) if (pos[i] == pos[j] || i == j || i + pos[i] == j + pos[j] || i - pos[i] == j - pos[j]) return false; } return true; } // 输出当前方案 void outPlan() { tot++; cout << "No. " << tot << "\n"; for (int i = 1; i <= 8; i++) { for (int j = 1; j <= 8; j++) if (pos[j] == i) cout << "1 "; else cout << "0 "; cout << "\n"; } } // 从第 now 层开始考虑 void dfs(int now) { // 前 n 层考虑完了,就检查一下 if (now > n) { if (check()) outPlan(); return; } // 考虑当前这一层,然后做下一层 for (int i = 1; i <= 8; i++) { // 考虑第 now 层放在 i 的位置 pos[now] = i; dfs(now + 1); } } int main() { ios::sync_with_stdio(false); cin.tie(0); tot = 0; dfs(1); // 从第一层考虑每层选几 return 0; }
搜索进阶,在每列放之前先检查
#include <bits/stdc++.h> using namespace std; int n = 8, tot; // n 皇后,tot 种方案 // pos[i] 记录第 i 列的皇后出现在哪儿 int pos[10]; // 输出当前方案 void outPlan() { tot++; cout << "No. " << tot << "\n"; for (int i = 1; i <= 8; i++) { for (int j = 1; j <= 8; j++) if (pos[j] == i) cout << "1 "; else cout << "0 "; cout << "\n"; } } // 从第 now 层开始考虑 void dfs(int now) { // 前 n 层考虑完了,就检查一下 if (now > n) { outPlan(); return; } // 考虑当前这一层,然后做下一层 for (int i = 1; i <= 8; i++) { // 考虑第 now 层放在 i 的位置 pos[now] = i; bool flag = true; // 一开始认为这个位置可以 for (int j = 1; j <= now - 1; j++) { // 考虑 (pos[now],now) 与 (pos[j],j) 如果冲突了,就不行 if (pos[now] == pos[j] || now == j || pos[now] + now == pos[j] + j || pos[now] - now == pos[j] - j) { flag = false; break; } } if (flag) dfs(now + 1); } } int main() { ios::sync_with_stdio(false); cin.tie(0); tot = 0; dfs(1); // 从第一层考虑每层选几 return 0; }
搜索最终,用额外数组标记,但要注意撤回标记
#include <bits/stdc++.h> using namespace std; int n = 8, tot; // n 皇后,tot 种方案 // pos[i] 记录第 i 列的皇后出现在哪儿 int pos[10]; // 输出当前方案 void outPlan() { tot++; cout << "No. " << tot << "\n"; for (int i = 1; i <= 8; i++) { for (int j = 1; j <= 8; j++) if (pos[j] == i) cout << "1 "; else cout << "0 "; cout << "\n"; } } // 从第 now 层开始考虑 bool flag1[10], flag2[20], flag3[20]; void dfs(int now) { // 前 n 层考虑完了,就检查一下 if (now > n) { outPlan(); return; } // 考虑当前这一层,然后做下一层 for (int i = 1; i <= 8; i++) { // 考虑第 now 层放在 i 的位置 pos[now] = i; // 考虑 (pos[now],now) 这个情况之前没有出现过时,才继续做 if (!flag1[pos[now]] && !flag2[pos[now] + now] && !flag3[pos[now] - now + 8]) { // 之后的情况中,pos[now]这一行不能放了 flag1[pos[now]] = true; // 之后的情况中,行列相加为 pos[now]+now 的情况不能出现了 flag2[pos[now] + now] = true; // 之后的情况中,行列相减为 pos[now]-now 的情况不能出现了 flag3[pos[now] - now + 8] = true; dfs(now + 1); // 还原为没有放在 pos[now] 的情况 flag1[pos[now]] = false; flag2[pos[now] + now] = false; flag3[pos[now] - now + 8] = false; } } } int main() { ios::sync_with_stdio(false); cin.tie(0); tot = 0; dfs(1); // 从第一层考虑每层选几 return 0; }
信息
- ID
- 433
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 117
- 已通过
- 38
- 上传者