回溯問題二:八皇后問題
阿新 • • 發佈:2018-11-30
程式設計五大思想之一,回溯。接下來兩天要用回溯解決以下問題:
(1)八皇后問題
(2)0-1揹包問題
(3)旅行售貨員問題
(4)裝載問題
(5)迷宮問題
(6)圖的m著色問題
(7)排列組合問題
問題一:八皇后問題
在8×8格的國際象棋上擺放八個皇后,使其不能互相攻擊,即任意兩個皇后都不能處於同一行、同一列或同一斜線上,問有多少種擺法?有趣的是,數學家高斯認為有96種方案,象棋高手認為有40種方案,計算機學家解出92種方案。本篇用C語言解出92種解:
程式設計思路:
把位置定義成結構體,c[i].x表示行,c[i].x表示列,i從第0行開始,每一行因為要找一個皇后,故要找八次,也就是八次函式遞迴。每一行都從列0開始找,0到第8列依次找,找到了儲存在c[i]進入下一行找,此時遞迴find_que(i+1);每一行找到了不代表這行就不找其他的了,還要找其他的,因為方案有很多種,這裡體現回溯思想
#include <stdio.h>
typedef struct//每個位置定義成一個結構體型別,該位置由行x列y組成
{
int x;
int y;
} Location;
int cheak(int i,Location c[])
{
int j;
for(j=0; j<c[i].x; j++)
{
///判斷在不在行、列、正、負對角線上
if((c[i].x==c[j].x)||(c[i].y==c[j].y)||((c[j].y-c[i].y)==(c[j].x-c[i].x))||((c[j].y- c[i].y)==(-1*(c[j].x-c[i].x))))
{
return 0;
}
}
return 1;
}
int count=0;//計數
void find_que(int i,int n,Location c[])
{
if(i==n)//八個已經找到了,輸出
{
int k;
for(k=0; k<n; k++)
{
printf("(%d,%d) ",c[k].x,c[k].y);
}
t++ ;
printf("\n");
}
else
{
int j=0;
for(j=0; j<n; j++)
{
c[i].x=i;///行
c[i].y=j;//列
if(cheak(i,c))//每個位置都判斷下
{
//printf("(%d,%d)---- ",c[i].x,c[i].y);
find_que(i+1,n,c);///本行i已經找到了,那麼進入下一行i+1找
}
}
}
}
main()
{
Location c[8];///可能所在的八個未知點
find_que(0,8,c);
printf("\n總數:%d",t);
}