1. 程式人生 > >兩種不同方式解決八皇后問題

兩種不同方式解決八皇后問題

問題描述

八皇后問題是一個以國際象棋為背景的問題:如何能夠在8×8的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?為了達到此目的,任兩個皇后都不能處於同一條橫行、縱行或斜線上。

解決思路

這個問題可以有兩種解決方法,一種是使用遞迴,比較簡單易懂,另一種是使用棧,利用棧的特性避免了遞迴的使用,從而提高了效率(遞迴的雖然簡單易寫,但是其效率往往較低)。

具體實現

首先將節點的座標定義為結構體:

typedef struct {
 int x;
 int y;
} Coord;

定義好judge函式(用於判斷對應點座標是否可以放置皇后):

bool judge(SqStack S, int x, int y) {
    SqStack m = S;
    while (!StackEmpty(m)) {
        Coord e;
        e = Pop(m);
        if ((e.x == x) || (abs(e.x - x) == abs(e.y - y))) {
            return false;//如果不行返回false
        }
    }

    return true;//如果可以返回true
}

遞迴

void Recursive(SqStack &S, int y) {

    if (StackEmpty(S)) {
        for (int i = 1; i <= N; ++i) {
            Coord e;
            e.x = i;
            e.y = 1;
            Push(S, e);
            Recursive(S, 2);
            Pop(S);
        }
    } else if (Full(S)) {
        StackTraverse(S);
        n++;
        return;
    } else {
        for (int i = 1; i <= N; ++i) {
            if (judge(S, i, y)) {
                Coord e;
                e.x = i;
                e.y = y;
                Push(S, e);
                Recursive(S, y + 1);
                Pop(S);
            }
        }
    }
}

這裡要注意遞迴呼叫Recurive之後要pop出遞迴之前push進去的,有進就要有出~

非遞迴

void Search(SqStack s) {

    int i = 1;
    bool flag;

    Coord e;
    e.x = 0;
    e.y = 1;

    while (i <= 8) {

        if (flag) {
            e.x = 0;
        }
        if (Full(s)) {
            e = Pop(s);

        }
        flag = false;

        for (int j = e.x + 1; j <= 8; j++) {
            if (judge(s, j, i)) {
                Coord e2;
                e2.x = j;
                e2.y = i;
                Push(s, e2);
                //  cout << "a" << i << "(" << e.y << "," << e.x << ") ";
                flag = true;
                break;
            }
        }


        if (flag) {
            if (i == 8) {
                StackTraverse(s);
                num++;

            } else {
                i++;
            }
        } else {
            i--;
            e = Pop(s);
            if (i == 0) {
                break;
            }
        }

    }
}