/*
八皇后问题是典型的回溯法的使用
在使用回溯法的时候,最主要的问题是标记已经使用的方案,然后向下搜索,结束搜索以后,取消标记
*/
#include <iostream>
#include<cstdio>
#include<string>
#include<map>
#include<vector>
#include<sstream>
#include<string.h>
using namespace std;
int kase=0;//方便打印时候提示第几种解法
int m[8][8];//八皇后棋盘
int dia[15],ant[15];//分别记录对角线和反对角线上有没有元素占用
void mark(int x,int y){//当有一个皇后位置确定时候,修改相应的棋盘,对角线和反对角线的标记
m[x][y]=1,dia[x+y]=1,ant[x-y+7]=1;
}
void demark(int x,int y){//当有一个皇后的位置撤销的时候,修改相应的棋盘,对角线和反对角线的标记
m[x][y]=0,dia[x+y]=0,ant[x-y+7]=0;
}
bool jud(int x,int y){//判断(x,y)处能否放置一个皇后
if(dia[x+y]||ant[x-y+7])return false;
for(int i=0;i<8;++i){
if(m[x][i]||m[i][y])return false;
}
return true;
}
void print(){
printf("Case: #%d\n",++kase);
for(int i=0;i<8;++i){
for(int j=0;j<8;++j){
if(j)printf(" ");
printf("%c",m[i][j]==1?'*':'_');
}
printf("\n");
}
}
void dfs(int x){//确定第x行皇后的位置
if(x==8){
print();
return;
}
for(int i=0;i<8;++i){
if(jud(x,i)){
mark(x,i);
dfs(x+1);
demark(x,i);
}
}
}
int main()
{
memset(m,0,sizeof(m));
memset(dia,0,sizeof(dia));
memset(ant,0,sizeof(ant));
dfs(0);
return 0;
}