您的位置:首页 > 其它

MOOC清华《程序设计基础》第5章第2题:破损棋盘的八皇后问题

2017-07-15 17:56 246 查看
题目描述

8X8的国际象棋棋盘上被挖了一些洞,这些洞不能放棋子,求八皇后问题的摆放方案,输出一种方案即可

输入格式

棋盘用.表示正常格子,用#表示被挖掉的洞,一共8行8列
输出格式

输出从上到下的每一行的皇后所在列号(1-8)

注意:只输出列号,只输出列号,最后的输出应该只是8个数字,第i个数字表示第i行的皇后在第几列,中间以空格隔开。
样例输入

........
..##....
####....
........
........
........
........
....####

样例输出

6 2 7 1 4 8 5 3


#include <iostream>
using namespace std;

const int Normalize = 9; //用来统一数组下标

int Num = 0; //方案数
int q[9]; //8个皇后所占用的行号
char incomplete[9][9]; //记录残破棋盘的各个格子,注意是字符类型

bool C[9]; //S[1]~S[8],当前列是否安全
bool L[17]; //L[2]~L[16],(i - j)对角线是否安全
bool R[17]; //R[2]~R[16],(i + j)对角线是否安全

void Try(int row)
{
for(int col = 1; col <= 8; col++)
//依次尝试当前的8列位置
{
//判断拟放置皇后的位置是否安全
if(C[col] && L[row - col + Normalize] && R[row + col] && incomplete[row][col] != '#')
{
//记录位置信息(行号)
q[row] = col;

//修改三个方向的安全性标记
C[col] = false;
L[row - col + Normalize] = false;
R[row + col] = false;
//核心技巧其实在后面这两行里,只有这样调整,对角线的下标才
//统一地从2到16,两个方向的平行对角线都是15条

if(row < 8)
{
//递归尝试放下一行
Try(row + 1);
}
else
{
Num++;
if(Num == 1)
for(int k = 1; k <= 8; k++)
cout << q[k] << " ";
}

//回溯:恢复三个方向原有安全性
C[col] = true;
L[row - col + Normalize] = true;
R[row + col] = true;
}
}
}

int main()
{
for(int i = 0; i < 9; i++)
C[i] = true;
for(int i = 0; i < 17; i++)
{
L[i] = true;
R[i] = true;
}

for(int i = 1; i < 9; i++)
{
for(int j = 1; j < 9; j++)
cin >> incomplete[i][j];
}

Try(1); //从第1行开始放皇后

return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐