八皇后问题
第一个博客,好鸡儿激动
咳咳,本菜鸡写了半天的代码,大佬轻喷
所谓八皇后问题就是在8*8的棋盘中放置八个皇后,保证每行每列每条斜线都只有一个皇后,典型的dfs深搜,不过实现起来也不是轻而易举的,此前需要一定的规划
我们定义如下变量:
1.int chess[8]用来记录每行皇后的纵坐标(每行肯定有且只有一个,所以不用管横坐标),-1表示还未落在棋盘上
2.int mp[8][8]棋盘
3.int mem[8][8]用来标记每个棋子是否已经落过这个点
我们定义如果mp[i][j]在某个皇后的攻击范围内,则该点的值大于0,否则等于0,如果某个皇后已经落过了某个点,则mem[i][j]=1,否则=0
下面是思路:
dfs(int t)//表示轮到第t个皇后上场了(t从0到7)
1.如果该皇后在场上,则取出
2.在该行上找不在其他皇后攻击范围内且没有标记的点
①存在该点
将皇后落至该点并标记该点
t++
若t=8则将当前情况保存下来,t–
dfs(t)
②不存在该点
将当前整行的标记全部取消(接下来将回退至上一个皇后,这意味着当前皇后走过的点只要之前的皇后布置有所变动,则该皇后落在之前走过的点也不会引起重复)
t–
若t=-1则所有情况已遍历完(第一个皇后已经走到第八列了)
否则dfs(t)
代码如下
#include<iostream>
#include<string.h>
using namespace std;
int a[100][8],anum=0;//用来保存满足条件的情况中皇后的列坐标
int chess[8];//每个皇后的列坐标 ,-1表示未加入棋盘
int mp[8][8];
int mem[8][8];//标记
void PUT(int x,int y)
{
for(int i=0;i<8;i++)
{
mp[x][i]++;
mp[i][y]++;
}
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i++,j++)
mp[i][j]++;
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i++,j--)
mp[i][j]++;
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i--,j++)
mp[i][j]++;
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i--,j--)
mp[i][j]++;
}
void PULL(int x,int y)
{
for(int i=0;i<8;i++)
{
mp[x][i]--;
mp[i][y]--;
}
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i++,j++)
mp[i][j]--;
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i++,j--)
mp[i][j]--;
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i--,j++)
mp[i][j]--;
for(int i=x,j=y;i>=0&&i<8&&j>=0&&j<8;i--,j--)
mp[i][j]--;
}
void dfs(int t)
{
if(chess[t]>=0)
PULL(t,chess[t]);//很重要,别忘了
int x=-1;
for(int i=0;i<8;i++)
if(mp[t][i]==0&&mem[t][i]==0)
{
x=i;
break;
}
if(x>=0)
{
chess[t]=x;
PUT(t,x);
mem[t][x]=1;
t++;
if(t==8)
{
for(int i=0;i<8;i++)
a[anum][i]=chess[i];
anum++;
t--;
}
dfs(t);
}
else
{
chess[t]=-1;
for(int i=0;i<8;i++)
mem[t][i]=0;
t--;
if(t>=0)
dfs(t);
}
}
int main()
{
memset(mp,0,sizeof(mp));
memset(mem,0,sizeof(mem));
memset(chess,-1,sizeof(chess));
dfs(0);
cout<<anum<<endl;
for(int i=0;i<anum;i++)
{
for(int j=0;j<8;j++)
cout<<a[i][j]<<" ";
cout<<endl;
}
}