八皇后問題自我總結

mutinner發表於2016-11-05

八皇后

Description

在國際象棋棋盤上放置八個皇后,要求每兩個皇后之間不能直接吃掉對方。

Input

No
Output
輸出所有八皇后問題的解
註解:在國際象棋中,皇后可以吃掉在同一行、列、斜線的其他的棋子。


        八皇后是一個經典的題目(作為一個菜鳥這是我碰到的比較難的一個題,所以自我總結一下,大佬請直接跳過)
        在本題中我使用的是c語言(菜鳥只會這個,還在學習中)。
        在整個程式碼中我用三個不同的函式(printarray,check,placeQueen)來解決問題,printarray用來輸出最後的解,check用來檢查當前放置的棋子是否符合題意,planeQueen(dfs)用來不停地放置棋子。
        我用一個一維陣列來表示一個解,用printarray來翻譯這個一維陣列使其變成最後的答案。
                                                                   例:04752613:
1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
        如上圖所示:每一位數字都代表一行中第n+1位有一枚棋子,第一位數字為0,第一行的0+1位就表示有一個皇后。
        其中check函式中來檢查當前放置的棋子是否正確,diff=abs(chess[row]-chess[i]),diff==0時代表有同一列有多個皇后,diff==row-i時代表在同一斜線上有多個皇后(因為在這個一維陣列中每一位數代表一枚棋子的位置,所以不存在同一行有兩個棋子)。
        placeQueen函式使用了dfs演算法,chess[row]=i代表落入一個棋子,然後用check函式來檢查對錯,一旦錯誤這一路徑將終結,正確將開始下一次計算,只有當row==N時,當前的一維陣列才是正確的,用printarray函式來輸出答案。
#include<stdio.h>
#include<math.h>
#define N 8
int chess[N];
int num=1;
int main(){
	void printarray(int[]);
	int check(int);
	void placeQueen(int);
	placeQueen(0);
	return 1;
}

void printarray(int data[8]){
	int i,j;
	printf("No.%2d:\n",num++);
	for(j=1;j<=N;j++){
	for(i=0;i<N;i++)
	if(i==data[j-1])printf("1 ");
	else printf("0 ");
	printf("\n");
	}
}

int check(int row){
	int i;
	for(i=0;i<row;i++){
		int diff=abs(chess[row]-chess[i]);
		if(diff==0||diff==row-i)return 0;
	}
	return 1;
}

void placeQueen(int row){
	int i;
	if(row==N){
		printarray(chess);
		return;
	}
	else for(i=0;i<N;i++){
		chess[row]=i;
		if(check(row))
		placeQueen(row+1);
	}
}
        如果有需要的朋友,可以轉載本文。



 

相關文章