相信大家对这个不陌生了 我也就再写一遍这是很经典的题目了
题意描述:
N皇后问题也是8皇后 换汤不换药
在N*N的方格棋盘放置了N||8个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在与棋盘边框成45角的斜线上。
你的任务是,对于给定的N,求出有多少种合法的放置方法。
(N<=10;)
输出:对应输入行的皇后的不同放置数量。
1:回溯法:
#include <iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int judge(int k);
int a[21];
int main(int argc, char const *argv[])
{
int k,n,sum,b[11],i;
k = 1; sum = 0;
a[k] = 0;
for(n=1;n<=10;n++){ //for循环就是一个简单的预处理 把1-10的情况都存放在数组里 别误导大家了
k = 1; sum = 0;a[k] = 0; //这一句就是每一次处理时的初始化
while(k>0){
a[k]++; //数组里面存放的数值代表列数
while((a[k]<=n)&&(!judge(k))){
a[k]++;
}
if(a[k]>n){
k--; //此处判断的是界 对了所有下标是从1算的不是0 。
}
else{
if(k==n){
sum++;
}
else{
k++;
a[k] = 0;
}
}
}
b[n] = sum; // sum 为 n 个皇后时的有可能的情况
}
while(scanf("%d",&i),i){
printf("%d\n",b[i]);
}
return 0;
}
int judge(int k){
int i;
for(i=1;i<k;i++){
if((a[i]==a[k])||(abs(i-k)==abs(a[i]-a[k]))){ //前半句是判断是否列相同 后半句判断对角线
return 0;
}
}
return 1;
}
我在网上看到过一篇写的很好的博客 这个写的和我的很类似而且比我详尽的优化的好
大家如果看不太懂我的一些步骤可以再看下这个。
https://blog.csdn.net/u014082714/article/details/44901575
2:DFS
#include<bits/stdc++.h>
using namespace std;
int sum=0;
int a[8]= {0};
int judge(int row,int line)
{
int i;
for(i=0;i<row;i++)
{
if(a[i]==line||abs(a[i]-line)==row-i)//同一行上肯定没有2个棋子了
return 0; // 判断同一列跟对角线上有没有棋子即可只判断该行之前的所有的行即可
} //跟上面回溯法比较这里是个小小的优化
return 1;
}
//void print() 这里是打印图形 想不明白的话可以用上
//{
// int i,j;
// printf("case:%d \n",++sum);
// for(i=0;i<8;i++)
// {
// for(j=0;j<8;j++)
// {
// if(a[i]==j)
// printf("%d",j);//a[i]==哪一列就说明该行的棋子放在了哪一列
// else
// printf("#");
// }
// printf("\n");
// }
// printf("\n");
//}
void dfs(int row)
{
int line;
for(line=0; line<8; line++)
{
if(judge(row,line))//判断此处是否可以放置
{
a[row]=line;//记录位置
if(row==7)//退出
print();
else
dfs(row+1);//否则继续走下一行
}
}
}
int main()
{
dfs(0);//从第0行开始 遍历
printf("%d\n",sum);
return 0;
}
emm这个没什么好讲的相信大家都看得懂