/*
將陣列rows初始為一儲存八個元素之陣列,
進入主程式後開始for迴圈,先將第0個位置,
也就是棋盤上的(1,1)佔據,然後開始找第二排的旗子可放之處,
也就是棋盤上的(2,1)開始放棋,以此類推,
跑到if判斷式後進入Valid函數開始檢查,
首先檢查rows[i] == rows[j],若等式成立代表兩個棋子在同一y軸上,
固直接傳回0的值,再找尋下一個棋子擺放處是否正確;
若rows[i] == rows[j]等式不成立,則將rows[i]-rows[j]的值傳給bevel,
此bevel變數代表右下角的斜邊是否有擺放棋子,
若等於j-i則代表在目前的棋子的斜邊上有棋子占據,所以傳回0,
若小於0則代表斜邊目前沒有棋子占據,固將傳回1,
則int main()中的if條件式成立,進入void answer(int rows[])將目前的解法印出。
*/
#include <stdio.h>
#define Q 8
void answer(int rows[]);
int valid(int rows[]);
static int count = 0;
int rows[Q];
void Queen (int i)
{
int j ;
if ( i < Q )
for (rows[i]=0 ; rows[i] < Q ; ) // 這兒不遞加, 由新增loop 決定
{
Queen (i+1);
rows[i]++ ; // 原本上層迴圈最後+1 搬到這兒
for ( j=0 ; j < i ; j++ ) // 增加檢查是否已經跟以前重複的迴圈
if ( rows[j] == rows[i] ) // 如果已經重複,
rows[i]++ ; // 則直接跳過該值, 換下一個
}
else if (valid(rows))
answer(rows);
}
int main()
{
Queen(0);
printf("一共有%d組解\n",count);
getchar();
printf("請按Enter鍵繼續...");
}
//副程式
int valid(int rows[])
{
int i, j;
int bevel;
for (i = 0; i < Q - 1; i++)
for (j = i + 1; j < Q; j++)
{
if (rows[i] == rows[j])
return 0;
bevel = rows[i] - rows[j];
if (bevel < 0)
bevel = -bevel;
if (bevel == j - i)
return 0;
}
return 1;
}
void answer(int rows[])
{
int i;
printf("第%d種解:",count + 1);
for (i = 0; i < Q; i++)
printf("%2d", rows[i] + 1);
printf("\n");
count++;
}
另外補上我依毒王講解所修改的程式碼,採用遞迴方式。
以經由DEV-C++編譯執行測試過,無誤! 有發現錯誤請指教^^"
sfredr 兄 也別忘了給我喔~呵呵
[GERRYccc 在 2005-4-11 03:55 PM 作了最後編輯]