1——带棋盘
#include<iostream>
using namespace std;
//八皇后问题 带棋盘
void Clear (char a[][20], int n);
void Show (char a[][20], int n);
void Queen (char a[][20], int n, int p);
int check (char a[][20], int n, int p, int k);
int main()
{
char a[20][20];
int n;//皇后的个数;
int p = 0;
cin >> n;
Clear(a,n);
Queen(a, n, p);
return 0;
}
void Clear (char a[][20], int n)
{
int i, j;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
a[i][j] = '.';
}
}
}
void Show (char a[][20], int n)
{
int i, j;
static int count = 0;
if(count)
{
putchar('\n');
}
cout<<"No."<<++count<<endl;
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
if(j)
{
cout<<' ';
}
cout << a[i][j];
}
putchar('\n');
}
}
void Queen (char a[][20], int n, int p)
{
int k;
if(p >= n)
{
Show(a, n);
}
else
{
for(k = 0; k < n; ++k)
{
if(check(a, n, p, k))//判断可以放皇后了
{
a[p][k] = 'Q';//p行k列为Q
Queen(a, n, p + 1);//下一行继续放皇后,直到放完n行
a[p][k] = '.';
}
}
}
}
int check (char a[][20], int n, int p, int k)
{
int i, j;
int ok = 1;
for (i = p - 1; ok && i >= 0; -- i)//看这一列有没有Q
{
ok = a[i][k] != 'Q'; //这句是下面注释内容的简化
// if(a[i][k] == '.')
// {
// ok = 1;
// }
// else
// {
// ok = 0;//ok为0停止,不符合条件
// }
}
for (int i = p - 1, j = k - 1; ok && i >= 0 && j >= 0; -- i, -- j)//看主对角线上部分
{
ok = a[i][j] != 'Q';
}
for (i = p - 1, j = k + 1; ok && i >= 0 && j < n; -- i, ++j )
{
ok = a[i][j] != 'Q';
}
return ok;
}
首先创立的棋盘是 20 X 20的大小,n皇后只需要 nXn就够了。之后先对棋盘进行清空,也就是能放棋子的位置都放置为“.”。
开始放置皇后,放置皇后的要求是该皇后的左上对角线,该列与右上对角线都没有皇后,check函数就是为了检验这个。
Queen函数应用了递归,出口就是第n行也放了皇后。
不带棋盘版
#include <iostream>
using namespace std;
//八皇后问题 不创建棋盘- -
int a[20];//下标为行数,值为列数;
int f1[20];// 对应列是否有皇后;
int f2[39];//主对角线
int f3[39];//副对角线
int n;//皇后丶个数
int p;//行数
int count = 0;
void Queen(int p);
void show();
int main()
{
cin >> n;
Queen(0);//第0 行;
return 0;
}
void Queen(int p)
{
int i, j;
int d1, d2, d3;
if(p >= n)
{
show();
}
else
{
for (a[p] = 0; a[p] < n; ++a[p])
{
d1 = a[p];
d2 = n - p + a[p] - 1;//副对角线行列有什么规律
d3 = p + a[p];//主对角线规律
if(!f1[d1] && !f2[d2] && !f3[d3])//对应线上的位置是空的,可以放置皇后
{
f1[d1] = f2[d2] = f3[d3] = 1;//表示这个位置被占了
Queen(p + 1);
f1[d1] = f2[d2] = f3[d3] = 0;
}
}
}
}
void show()
{
int i, j;
if(count)
{
putchar('\n');
}
++count;
cout << "No." <<count <<endl;
for (i = 0; i < n; ++ i)
{
for (j = 0; j < n; ++ j)
{
if(j)
{
putchar(' ');
}
putchar(j == a[i] ? 'Q' : '.');//如果列号和a[i]相同,i行a[i]列可放置
}
putchar('\n');
}
}
关键就是找 列 主对角线 副对角线 行与列之间的关系了;