#include<stdio.h>
#define N 8
int count=0;
int IsSafe(int row,int n,int (*chess)[N])
{
//判断列,斜向是否有冲突
//情况分为5种,左上,左下,右上,右下,本列
int i,j;
int flag;
flag=1;//安全
for(i=0;i<N;i++) //本列
{
if( 1 == chess[i][n])
{
flag=0;
break;
}
}
for(i=row,j=n;i>=0&&j>=0;--i,--j)//左上
{
if( 1 == chess[i][j])
{
flag=0;
break;
}
}
for(i=row,j=n;i<N&&j>=0;++i,--j)//左下
{
if( 1 == chess[i][j])
{
flag=0;
break;
}
}
for(i=row,j=n;i>=0&&j<N;--i,++j)//右上
{
if( 1 == chess[i][j])
{
flag=0;
break;
}
}
for(i=row,j=n;i<N&&j<N;++i,++j)//右下
{
if( 1 == chess[i][j])
{
flag=0;
break;
}
}
return flag;
}
// 参数row: 表示起始行
// 参数n: 表示列数
// 参数(*chess)[N]: 表示指向棋盘每一行的指针
void EightQueen(int row,int n,int (*chess)[N])//重点
{
//操作下标为 row 的那行
//复制整个棋盘
int chess2[N][N]={0};
int i,j;
for(i=0;i<N;++i)//复制,形成副本,然后操作副本
{
for(j=0;j<N;++j)
chess2[i][j]=chess[i][j];
}
//判断row==N,row==N代表溢出了,如果溢出了,就输出这种可能
//否则,继续填棋
if( N==row )//棋盘满了,输出副本
{
for(i=0;i<N;++i)
{
for(j=0;j<N;++j)
printf("%d ",chess2[i][j]);
printf("\n");
}
printf("\n\n");
count++; //出现一种可能
}
else //无溢出,棋盘未满,继续填棋
{
for(j=0;j<N;++j)//填充本行 的0到N-1列
{
if(IsSafe(row,j,chess2))//1:安全,row行j列填棋
{
for(i=0;i<N;++i)
chess2[row][i]=0;//为了数据安全,清空本行
chess2[row][j]=1;//row行j列填棋
EightQueen(row+1,n,chess2);//填充下一行
}
}
}
}
//*(*(chess+i)+j) (*chess)[N]
int main(int argc, char *argv[]) {
//主函数说明:
int chess[N][N]={0};
EightQueen(0,N,chess);
printf("%d皇后有%d种可能!\n\n",N,count);
return 0;
}
本人的拙见 |