很久之前就写过这题了,一直似懂非懂,今天终于彻底理解了
问题描述:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
算法思路:在一个棋盘中,一行一行的放置皇后。放当前位置的时候,要考虑会不会和之前放置好的皇后相互攻击。如果相互攻击,就把皇后放在此行的下一列,即往右移一个位置。直到满足条件,又开始放置下一行的皇后。所以,两个皇后不会处在同一行。我用来判断不在同一斜线的方法为:把棋盘看作为二维坐标,那么两个皇后如果在一条线上,那么他们的横坐标相减的绝对值等于他们的纵坐标相减的绝对值。
#include<iostream>
#include<cmath>
using namespace std;
const int n=8;
int col[n+10]; //一维数组,下标代表列,col[]代表行
int ans;
void dfs(int row) //row 代表此时皇后所在的行
{
if(row==n)
{
ans++;
return;
}
int i,j;
for(i=0;i<n;i++) //i代表列
//如果本行的i列不能放,
//就换个位置,右移到下一列
{
col[row]=i; //记录行的坐标
int f=1;
for(j=0;j<row;j++)//j代表行,只需遍历到之前的所有行即可
{
if(col[row]==col[j]||abs(j-row)==abs(col[row]-col[j]))
{
f=0;
break;
}
}
if(f)
dfs(row+1);
}
}
int main()
{
dfs(0);
cout<<ans;
return 0;
}
作为一个菜鸟,深深地体会到了这个题目的坑点,所以我已经把所有可以注释的地方都注释了,希望初学者能看懂^_^