八皇后问题所有解枚举

#include "stdafx.h"

//int taken[8][8];    // 存储该地方被皇后攻击到, 0--没有攻击到, >0被攻击到
int allstone[8][8];    // 存储该地方是否有皇后,1--代表有皇后,0--代表没有

class NUM_STACK
{
public:
    NUM_STACK(){
        iTop = -1;
    }

    bool push(int iNum)
    {
        iTop++;
        if(iTop >= 8){
            iTop--;
            return false;
        }
        _stack[iTop] = iNum;
        return true;
    }

    bool pop(int& iNum)
    {
        if(iTop == -1){
            return false;
        }
        iNum = _stack[iTop];
        iTop--;
        return true;
    }
    int get_size()
    {
        return iTop+1;
    }
    bool get_value(int index, int& iValue)
    {
        if(index+1 > get_size()){
            return false;
        }
        iValue = _stack[index];
        return true;
    }
protected:
    int _stack[8];
    int iTop;
};

struct NUM_ELEM
{
    int iNum;
    bool bTake;
};

class NUM_ARRAY
{
public:
    NUM_ARRAY(){
        int ii;
        for(ii=0;ii<8;ii++){
            _array[ii].iNum = ii;
            _array[ii].bTake = false;
        }
    }

    void take_next_num(int& iNum)
    {
        iNum++;
        while(iNum < 8){
            if(!_array[iNum].bTake){
                break;
            }
            iNum++;
        }
        if(iNum >= 8){
            iNum = -1;
            return;
        }
        _array[iNum].bTake = true;
        iNum = _array[iNum].iNum;
    }

    void release_num(int iNum)
    {
        if(iNum<0 || iNum >= 8){
            return;
        }
        _array[iNum].bTake = false;
    }

protected:
    NUM_ELEM _array[8];
};

bool take_pos(int x, int y, bool bTaken = true)
{
    //int ii;
    //if(bTaken){
    //    if(allstone[x][y] == 1){
    //        return false;
    //    }
    //}else{
    //    if(allstone[x][y] != 1){
    //        return false;
    //    }
    //}

    //int delta = bTaken ? 1 : -1;
    //// 行
    //for(ii=0;ii<8;ii++){
    //    taken[x][ii] += delta;
    //}

    //// 列
    //for(ii=0;ii<8;ii++){
    //    taken[ii][y] += delta;
    //}

    //// 从左到右下移
    //int k = (x < y) ? x : y;
    //for(ii=0;ii<8;ii++){
    //    if(x-k+ii >= 8 || y-k+ii >= 8){
    //        break;
    //    }
    //    taken[x-k+ii][y-k+ii] += delta;
    //}

    //// 从右到左下移
    //k = (7 - x < y) ? 7 - x : y;
    //for(ii=0;ii<8;ii++){
    //    if(x+k-ii < 0 || y-k+ii >= 8){
    //        break;
    //    }
    //    taken[x+k-ii][y-k+ii] += delta;
    //}

    if(bTaken){
        allstone[x][y] = 1;    // 占用
    }else{
        allstone[x][y] = 0;    // 拔起
    }
    return true;
}

bool check_and_take(int x, int y)
{
    if(allstone[x][y] == 1){
        return false;
    }

    int ii;
    // 检查路线上是否有其他皇后
    // 检查行
    for(ii=0;ii<8;ii++){
        if( allstone[x][ii] == 1){
            return false;
        }
    }

    // 检查列
    for(ii=0;ii<8;ii++){
        if( allstone[ii][y] == 1){
            return false;
        }
    }

    // 检查从左到右下移
    int k = (x < y) ? x : y;
    for(ii=0;ii<8;ii++){
        if(x-k+ii >= 8 || y-k+ii >= 8){
            break;
        }
        if(allstone[x-k+ii][y-k+ii] == 1){
            return false;
        }
    }

    // 检查从右到左下移
    k = ( 7 - x < y) ? 7 - x : y;
    for(ii=0;ii<8;ii++){
        if(x+k-ii < 0 || y-k+ii >= 8){
            break;
        }
        if( allstone[x+k-ii][y-k+ii] == 1){
            return false;
        }
    }

    return take_pos(x, y);
}

int _tmain(int argc, _TCHAR* argv[])
{
    NUM_ARRAY num_array;
    NUM_STACK num_stack;

    int iRow = 0;
    int iCol = 0;
    int iIndex = -1;

    int iAll = 0;

    //while(iRow>=0 && iRow<8){
    while(iRow>=0){
        if(iRow >= 8){
            iRow--;
            num_stack.pop(iCol);
            num_array.release_num(iCol);
            take_pos(iRow, iCol, false);
            iIndex = iCol;
        }
        
        num_array.take_next_num(iIndex);
        iCol = iIndex;
        while(iCol>=0){

            if(check_and_take(iRow, iCol)){
                num_stack.push(iCol);
                iRow++;
                break;
            }else{
                num_array.release_num(iCol);
                num_array.take_next_num(iCol);
            }
        }
        if(iCol<0){
            if(iRow>0){
                iRow--;
                num_stack.pop(iCol);
                num_array.release_num(iCol);
                take_pos(iRow, iCol, false);
                iIndex = iCol;
            }else{
                // 枚举完成,退出
                break;
            }
        }else{
            if(num_stack.get_size() == 8){
                // 找到一组解
                int ii;
                iAll++;
                printf("%d: ",iAll);
                for(ii=0;ii<8;ii++){
                    int iCol;
                    num_stack.get_value(ii, iCol);
                    printf("(%d,%d) ", ii+1, iCol+1);
                }
                printf("\r\n\r\n");
            }else{
                iIndex = -1;
            }
        }
    }

    if(iAll == 0){
        printf("无解\r\n\r\n");
    }

    return 0;
}

 

posted on 2017-07-12 14:30  litandy  阅读(912)  评论(0编辑  收藏  举报

导航