N皇后问题 (20 分)
在N * N的方格棋盘上,放置N个皇后,要求每个皇后不同行,不同列,不同左右对角线。 其中N不超过10。 要求:输出所有的解。
输入格式:
输入N
输出格式:
逐行输出每一种解,用每个皇后的位置坐标表示,每个位置坐标之后均有一个空格符,输出最后一行为空行。
输入样例:
在这里给出一组输入。例如:
6
输出样例:
在这里给出相应的输出。例如:
1: (1,2) (2,4) (3,6) (4,1) (5,3) (6,5)
2: (1,3) (2,6) (3,2) (4,5) (5,1) (6,4)
3: (1,4) (2,1) (3,5) (4,2) (5,6) (6,3)
4: (1,5) (2,3) (3,1) (4,6) (5,4) (6,2)
答案代码:
```
#include<stdio.h>
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
int chess[10][10] = { 0 };
int count = 0;
//判断是否能放入皇后,不能则返回0,能则为1
void output(int(*chess)[10], int n)
{
int i, j;
printf("%d: ", count);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
if (chess[i][j] == 1)
{
printf("(%d,%d) ", i + 1, j + 1);
}
}
}
printf("\n");
}
int canput(int i, int j, int(*chess)[10], int n)
{
int s = 0;
for (int k = i - 1; k >= 0; k--)
{
s++;
if (chess[k][j] == 1 || j + s < n&&chess[k][j + s] == 1 || j - s >= 0 && chess[k][j - s])//这种就比较暴力,每一行每一列都是试过去
{
return 0;
}
}
return 1;
}
void queen(int n, int l)
{
if (l == n - 1)
{
for (int j = 0; j < n; j++)
{
if (canput(l, j, chess, n))
{
count++;
chess[l][j] = 1;
output(chess, n);
chess[l][j] = 0;
}
}
}
else
{
for (int j = 0; j < n; j++)
{
chess[l][j] = 1;
if (canput(l, j, chess, n))
{
queen(n, l + 1);
}
chess[l][j] = 0;
}
}
}
int main()
{
int n;
cin >> n;
queen(n, 0);
return 0;
}```
第一次的棋盘。
递归求解的N皇后问题其实是一种比较暴力的方法,那就是每一个点都试过去,如果这个点可以放,那么就赋值为1。这么做其实是比较耗空间和时间的,但是简单。(能对就行了)
这里借鉴了一位老哥的canput函数,本来是想学小甲鱼那种全部都扫过去看可不可以的方法,后来去搜的时候发现了这种比较好用的方法,这种方法的判断是否可以放是用类似于深搜的方法?其实皇后问题只要判断在要落子的皇后前面的十字棋盘中有没有皇后就可以了
最后,每个递归的出口就是当第一个落子的皇后放到最后一行的时候,递归就结束了。