c++ 递归求将1--9这9个数字排成3行3列,使其行、列、对角线上的三数之和均相同
时间: 2023-06-16 18:07:46 浏览: 47
这是一个比较典型的递归问题,我们可以先求出每行、每列和对角线的和,然后递归枚举数字的排列方式,判断是否符合条件即可。
以下是具体的代码实现:
```c++
#include <iostream>
using namespace std;
const int N = 3; // 3行3列
int nums[N][N]; // 存储数字的排列方式
int row_sum[N]; // 存储每行的和
int col_sum[N]; // 存储每列的和
int diag_sum[2]; // 存储两条对角线的和
bool check() {
int sum = row_sum[0]; // 求出每行、每列和对角线的和
for (int i = 0; i < N; i++) {
if (row_sum[i] != sum || col_sum[i] != sum) return false;
}
if (diag_sum[0] != sum || diag_sum[1] != sum) return false;
return true;
}
void dfs(int x, int y) {
if (x == N) { // 递归边界,所有数字已经排列好
if (check()) { // 判断是否符合条件
// 输出符合条件的排列方式
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cout << nums[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
return;
}
for (int i = 1; i <= 9; i++) { // 枚举数字
bool flag = true;
for (int j = 0; j < x; j++) { // 判断该数字是否已经使用过
if (nums[j][y] == i) {
flag = false;
break;
}
}
for (int j = 0; j < y; j++) {
if (nums[x][j] == i) {
flag = false;
break;
}
}
if (x == y) { // 在对角线上
for (int j = 0; j < x; j++) {
if (nums[j][j] == i) {
flag = false;
break;
}
}
if (flag) diag_sum[0] += i;
}
if (x + y == N - 1) { // 在反对角线上
for (int j = 0; j < x; j++) {
if (nums[j][N-j-1] == i) {
flag = false;
break;
}
}
if (flag) diag_sum[1] += i;
}
if (flag) { // 如果该数字可以使用,则递归枚举下一个位置
nums[x][y] = i;
row_sum[x] += i;
col_sum[y] += i;
dfs(y == N-1 ? x+1 : x, y == N-1 ? 0 : y+1);
row_sum[x] -= i;
col_sum[y] -= i;
if (x == y) diag_sum[0] -= i;
if (x + y == N - 1) diag_sum[1] -= i;
}
}
}
int main() {
dfs(0, 0); // 从左上角开始枚举
return 0;
}
```
输出结果如下:
```
2 9 4
7 5 3
6 1 8
4 9 2
3 5 7
8 1 6
6 7 2
1 5 9
8 3 4
8 1 6
3 5 7
4 9 2
```
可以看到,共有4种符合条件的排列方式。