トップページに戻る    次のC++のサンプルへ    前のC++のサンプルへ

8-7 8王妃問題

問題

Eight queens puzzleを解きます。


ソース

#include <valarray>
#include <vector>
#include <stack>

bool IsValid(std::vector<std::valarray<bool> > &Ban, int targetX, int targetY);

void main()
{
    std::stack<std::vector<std::valarray<bool> > > stk;
    std::valarray<bool> wkArr(false,8);
    std::vector<std::valarray<bool> > Ban(8,wkArr);
    stk.push(Ban);

    int answerCnt = 0;
    while (stk.empty() == false) {
        Ban = stk.top(); stk.pop();

        int ouhiCnt = 0;
        for(std::vector<std::valarray<bool> >::iterator it = Ban.begin();it!=Ban.end();it++){
            for(int Y=0;Y<=7;Y++){
                if((*it)[Y]) ouhiCnt++;
            }
        }

        if (ouhiCnt == 8) {
            printf("\nanswer%d\n",++answerCnt);
            for (int X = 0; X <= 7; X++) {
                 for (int Y = 0; Y <= 7; Y++) {
                     if (Ban.at(X)[Y]) printf("1");
                     else printf("0");
                 }
                 puts("");
            }
            continue;
        }

        for (int Y = 0; Y <= 7; Y++) {
            if (IsValid(Ban, ouhiCnt, Y)) {
                std::vector<std::valarray<bool> > CopiedBan = Ban;
                CopiedBan.at(ouhiCnt)[Y] = true;
                stk.push(CopiedBan);
            }
        }
    }
}

bool IsValid(std::vector<std::valarray<bool> > &Ban, int targetX, int targetY)
{
    //横チェック
    for (int X = 0; X <= 7; X++){
        if (Ban.at(X)[targetY]) return false;
    }

    //左下チェック
    for (int X = targetX, Y = targetY; 0 <= X && X <= 7 && 0 <= Y && Y <= 7; X--, Y++){
        if (Ban.at(X)[Y]) return false;
    }

    //左上チェック
    for (int X = targetX, Y = targetY; 0 <= X && X <= 7 && 0 <= Y && Y <= 7; X--, Y--){
        if (Ban.at(X)[Y]) return false;
    }

    return true;
}


実行結果

省略
answer91
10000000
00000100
00000001
00100000
00000010
00010000
01000000
00001000

answer92
10000000
00001000
00000001
00000100
00100000
00000010
01000000
00010000


解説

ValArrayのVectorを2次元配列として使ってます。