八皇后问题回溯法

回溯法八皇后问题

#include <iostream>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>

#define print_board(board, ...) {\
    printf(__VA_ARGS__); \
    printf("\n"); \
    print_board_(board);\
}

#ifndef N
#define N 12
#endif

int solve();
bool check(int board[][N], int row, int col);
bool traceback(int board[][N], int& row, int& col);
void print_board_(const int board[][N]);

int main(int argc, char** argv) {
    clock_t start, end;
    start = clock();
    int count = solve();
    end = clock();
    printf("%d queens, %d resolutions, time cost: %.3f ms\n", N,
            count, ((end-start)*1000./CLOCKS_PER_SEC));

    return 0;
}

int solve() {
    int board[N][N]{0};
    int row = 0, col = 0, count = 0;
    while (1) {
        if (check(board, row, col)) {
            board[row][col] = 1;
            if (row == N-1) {
                ++count;
                print_board(board, "%d:", count);
                //break;
                traceback(board, row, col);
            } else {
                ++row;
                col = 0;
            }
        } else {
            if (col == N-1) {
                if (!traceback(board, row, col)) {
                    break;
                }
            } else {
                ++col;
            }
        }
    }
    return count;
}
bool traceback(int board[][N], int& row, int& col) {
    for (int i = N-1; i >= 0; --i) {
        for (int j = N-1; j >= 0; --j) {
            if (board[i][j] == 1) {
                board[i][j] = 0;
                if (j == N-1) {
                    if (i == 0) {
                        return false;
                    } else {
                        return traceback(board, row, col);
                    }
                } else {
                    row = i;
                    col = j + 1;
                    return true;
                }
            }
        }
    }
    return false;
}

bool check(int board[][N], int row, int col) {
    int diff = col - row;
    int sum = col + row;
    for (int i = 0; i < N; ++i) {
        if (board[row][i]==1 || board[i][col]==1
                || (i+diff>=0 && i+diff<N&& board[i][i+diff]==1)
                || (sum-i>=0 && sum-i<N&& board[i][sum-i]==1)) {
            return false;
        }
    }
    return true;
}

void print_board_(const int board[][N]) {
    for (int row = 0; row < N; ++row) {
        for (int col = 0; col < N; ++col) {
            if (board[row][col] == 1) {
                printf("★  ");
            } else {
                printf("☆  ");
            }
            if (col == N-1) {
                printf("\n");
            }
        }
    }
}

测试:

$ g++ -o eight_queen eight_queen.cpp -DN=8 && ./eight_queen
...
90:
☆  ☆  ☆  ☆  ☆  ☆  ☆  ★  
☆  ★  ☆  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ★  ☆  ☆  ☆  
☆  ☆  ★  ☆  ☆  ☆  ☆  ☆  
★  ☆  ☆  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ☆  ☆  ★  ☆  
☆  ☆  ☆  ★  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ☆  ★  ☆  ☆  
91:
☆  ☆  ☆  ☆  ☆  ☆  ☆  ★  
☆  ☆  ★  ☆  ☆  ☆  ☆  ☆  
★  ☆  ☆  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ☆  ★  ☆  ☆  
☆  ★  ☆  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ★  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ☆  ☆  ★  ☆  
☆  ☆  ☆  ★  ☆  ☆  ☆  ☆  
92:
☆  ☆  ☆  ☆  ☆  ☆  ☆  ★  
☆  ☆  ☆  ★  ☆  ☆  ☆  ☆  
★  ☆  ☆  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ★  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ☆  ★  ☆  ☆  
☆  ★  ☆  ☆  ☆  ☆  ☆  ☆  
☆  ☆  ☆  ☆  ☆  ☆  ★  ☆  
☆  ☆  ☆  ☆  ★  ☆  ☆  ☆  
8 queens, 92 resolutions, time cost: 2.882 ms
posted @ 2023-08-07 22:01  keep-minding  阅读(2)  评论(0编辑  收藏  举报