1213:八皇后问题
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 41676 通过数: 15755
【题目描述】
在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。
【输入】
(无)
【输出】
按给定顺序和格式输出所有八皇后问题的解(见样例)。
【输入样例】
(无)
【输出样例】
No. 1
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
No. 2
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0
...以下省略
思路
第一眼看到这题,就知道这题不简单,由于没下过国际象棋所以我看了好久的
题,最后我终于看懂了,其实这题不是很难,代码量很多,我把思路全写在代
码里力~
代码
#include <bits/stdc++.h>
using namespace std;
const int dx[9]={-1,-1,-1,0,0,1,1,1},dy[9]={-1,0,1,-1,1,-1,0,1};
//把上,下,左,右,上左,上右,下左,下右的数组全部标记
int vis[9][9],ans[9],tot;
bool check(int x, int y)
{
return (x>=1&&x<=8&&y>=1&&y<=8);//判断是否超出边界
}
void se(int x, int y) //标记八皇后能够攻击到的位置
{
++vis[x][y];
for (int o=0;o<8;o++)
{
int i=x,j=y;
while (check(i+dx[o],j+dy[o]))//循环标记到边界
{
i=i+dx[o],j=j+dy[o];
++vis[i][j];
}
}
}
void er(int x, int y) //擦除当前八皇后的标记
{
--vis[x][y];
for (int o=0;o<8;o++)
{
int i=x,j=y;
while(check(i+dx[o],j+dy[o])) //循环擦除八皇后的标记
{
i=i+dx[o],j=j+dy[o];
--vis[i][j];
}
}
}
void write()//输出每个八皇后的位置
{
++tot;
cout<<"No. "<<tot<<endl;
for (int i=1;i<=8;i++)
{
for (int j=1;j<=8;j++)
cout<<((j!=ans[i])?0:1)<<" ";
cout<<endl;
}
}
void dfs(int dep)
{
if (dep==9)
{
write();
return;
}
for (int i=1;i<=8;i++)
if (!vis[i][dep])
{
ans[i]=dep;
se(i,dep);
dfs(dep+1);
er(i,dep);
ans[i]=0;
}
}
int main()
{
dfs(1);//从第一行开始
}
关注!!!!!!!!