问题: n−皇后问题是指将 n 个皇后放在 n×n 的国际象棋棋盘上,使得皇后不能相互攻击到,即任意两个皇后都不能处于同一行、同一列或同一斜线上。
放置皇后代码实现:
int place(int k){
for(int i=1;i<k;i++)
if(x[i]==x[k]||abs(i-k)==abs(x[i]-x[k]))
return 0;
return 1;
}
思路 :放置第K行的皇后 从一行开始找 第K行的皇后是否能放下 x[i]==x[k] 判断是否是同一行 abs(i-k)==abs(x[i]-x[k]) 判断是否是对角线元素
递归代码实现:
void queens(int t){
// 如果放置的是 n以上的皇后了 说明n行都已经放上皇后了
if(t>n){
sum++;
return;
}else{
//一个一个位置的搜索 是否能放置皇后
for(int j=1;j<=n;j++){
x[t]=j;
if(place(t)) queens(t+1);
}
}
}
非递归代码实现:
void undigui_queens(int t){
//
int j=1;x[j++]=1;
//从1开始 当t==0时候结束循环
while(j>0){
//在j行 放置皇后
while(x[j]<=n&&!place(j))
x[j]++;
//放置完皇后 分情况 情况一(1)放置的皇后在n行里面 并且是最后一行则找到了答案 并且输出
//(2) 不是最后一行则另起一行 把皇后放到1号位置
//情况二 无法放置皇后或者说皇后在n格以外的位置去了 则返回上一个位置的皇后的下一个位置
if(x[j]<=n){
if(j==n){
output();
sum++;
x[--j]++;
}else
x[++j]=1;
}else x[--j]++;
}
}
全部代码:
#include<bits/stdc++.h>
using namespace std;
int x[10001],sum=0,n;
int place(int k){
for(int i=1;i<k;i++)
if(x[i]==x[k]||abs(i-k)==abs(x[i]-x[k]))
return 0;
return 1;
}
void output(){
for(int i=1;i<=n;i++){
cout<<x[i]<<" ";
}
cout<<endl;
}
void queens(int t){
// 如果放置的是 n以上的皇后了 说明n行都已经放上皇后了
if(t>n){
sum++;
return;
}else{
//一个一个位置的搜索 是否能放置皇后
for(int j=1;j<=n;j++){
x[t]=j;
if(place(t)) queens(t+1);
}
}
}
void undigui_queens(int t){
//
int j=1;x[j++]=1;
//从1开始 当t==0时候结束循环
while(j>0){
//在j行 放置皇后
while(x[j]<=n&&!place(j))
x[j]++;
//放置完皇后 分情况 情况一(1)放置的皇后在n行里面 并且是最后一行则找到了答案 并且输出
//(2) 不是最后一行则另起一行 把皇后放到1号位置
//情况二 无法放置皇后或者说皇后在n格以外的位置去了 则返回上一个位置的皇后的下一个位置
if(x[j]<=n){
if(j==n){
output();
sum++;
x[--j]++;
}else
x[++j]=1;
}else x[--j]++;
}
}
int main(){
cin>>n;
undigui_queens(1);
cout<<sum;
}
小白一个,欢迎讨论!!!