一. 問題描述
在國際象棋中,皇后棋子擁有最大的攻擊力ju,她除了可以像象棋中的‘車’一樣攻擊行和列,還可以攻擊四個斜方向的棋子,如圖:
紅線爲其攻擊範圍,那麼什麼是八皇后問題呢?
即在當前棋盤上,要擺放八個皇后棋子,且這八個皇后棋子,不能在彼此的攻擊範圍內,例如下面這種情況:
二. 思路分析
在第一行放置一顆棋子,來到第二行,放置棋子時,需要判斷這個位置是否危險,即該位置的列方向,斜方向是否有其他棋子存在(因爲行方向只能放一顆棋子),如果安全,則放下棋子,遞歸調用函數,直到第八顆棋子放置完畢後,打印棋盤目前的狀況
三. 代碼
#include <stdio.h>
int count = 1;
int notdanger(int row,int j,int (*chess)[8])
{
int i,k;
int flag1 = 0,flag2 = 0,flag3 = 0,flag4 = 0,flag5 = 0;
for(i = 0; i < 8; i++) //判斷列方向是否有棋子
{
if( *(*(chess+i)+j) != 0 )
{
flag1 = 1;
break;
}
}
for(i = row,k = j; i >= 0 && k >= 0; i--,k--) //判斷左上方是否有棋子
{
if( *(*(chess+i)+k) != 0)
{
flag2 = 1;
break;
}
}
for(i = row,k = j; i < 8 && k < 8; i++,k++) //判斷右下方是否有棋子
{
if( *(*(chess+i)+k) != 0)
{
flag3 = 1;
break;
}
}
for(i = row,k = j; i >= 0 && k < 8; i--,k++) //判斷右上方是否有棋子
{
if( *(*(chess+i)+k) != 0)
{
flag4 = 1;
break;
}
}
for(i = row,k = j; i < 8 && k >= 0; i++,k--) //判斷左下方是否有棋子
{
if( *(*(chess+i)+k) != 0)
{
flag5 = 1;
break;
}
}
if(flag1 || flag2 || flag3 || flag4 || flag5)
{
return 0;
}
else
{
return 1;
}
}
void EightQueens(int row,int n,int (*chess)[8]) //row表示當前進行到第幾行,n便是列數,chess表示指向某一行的指針
{
int chess_temp[8][8],i,j;
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
chess_temp[i][j] = chess[i][j];
}
}
if( 8 == row ) //遞歸結束
{
printf("第%d種\n",count++);
for(i = 0; i < 8; i++)
{
for(j = 0; j < 8; j++)
{
printf("%d ",*(*(chess_temp+i)+j));
}
printf("\n");
}
printf("\n");
}
else
{
for(j = 0; j < n; j++)
{
if( notdanger(row,j,chess))
{
for(i = 0; i < 8; i++)
{
*(*(chess_temp+row)+i) = 0; //將這一行的所有位置賦值爲0
}
*(*(chess_temp+row)+j) = 1; //將這個位置賦值1
EightQueens(row+1,n,chess_temp); //遞歸調用
}
}
}
}
int main(int argc, char *argv[])
{
int chess[8][8] = {0};
EightQueens(0,8,chess);
return 0;
}