Sicily 1276. Who needs 8 Queens w

来源:互联网 发布:适马17 50 f2.8数据 编辑:程序博客网 时间:2024/05/29 07:45

1276. Who needs 8 Queens w

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB , Special Judge

Description

The N -Queens problem is an obvious expansion of the eight-queens problem that has been around for a long time: Given a board with N x N squares and N queens, position the queens on the board such that no two queens can attack each other; in other words, so that no two queens sit on the same horizontal row, vertical column, or along either possible diagonal (row+column = k for one, row-column = k for the other).

Finding all the solutions to the problem for a given N is known to be worse than exponential in difficulty -O(N!) . One can, however, find a single solution to the problem in significantly less time if one looks beyond the standard backtracking solution to another possible solution strategy.

This problem asks you to find such a solution strategy. Note that the solution found may not necessarily be the one obtained first in the backtracking approach.

Since there is a huge number of candidate solutions for any but the very smallest values of N , the judges have access to a solution validation program. Consequently it is critical that you abide by the output specifications, since they constitute the input specifications for the validator.

Input

The input file begins with a line containing a single integer (no white space) specifying the number of problem specifications in the file. Exactly that many lines follow, each giving the value of N (with no white space) for which you are to solve the N -queens problem. The values of N may range from 4 up through 300; in other words, you should be able to find some solution to the 300-Queens problem in less than 120 seconds.

Output

For each problem, output on a single line that number (N ). Following that, give the permutation vector of column positions (0 through N - 1 ) that specify the queen's position on each succeeding row. The permutation vector is to be of N integers separated by white space. You may choose for yourself whether you use simple blanks for white space (giving the solution vector on one line) or you put each value on a separate line. In the interest of printing, the sample output here will use an approach that generates lines of values that do not exceed 65 characters in length. You are not held to that format. Then, the sample output is one of a very large number of possible outputs.

Sample Input

4 4 8 25 50

Sample Output

4  2 0 3 1 8  2 7 3 6 0 5 1 4 25  14 7 18 22 13 10 24 11 1 20 6 0 15 8 5 16 23 17 4 21 12 2 19 3 9 50  22 13 15 44 27 3 1 4 19 40 20 5 31 49 7 29 18 6 2 36 28 12 38 43  39 11 26 14 0 30 34 8 41 9 16 10 17 33 45 42 46 24 47 35 32 23 

25 37 21 48

// Problem#: 1276// Submission#: 3295608// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/// All Copyright reserved by Informatic Lab of Sun Yat-sen University#include <iostream>#include <vector>#include <algorithm>using namespace std;class Queen {public:    char QChar, BChar;  // 代表皇后和空白的字符    int * q_in_row;  // q_in_row[i] = j表示在第i行第j列有个皇后    bool * col_free;  // col_free[i] = true表示第i列没有皇后    bool * up_free;  // 从右上到左下的对角线是否可以放置皇后    bool * down_free;  // 从左上到右下的对角线是否可以放置皇后    int N;  // 皇后个数、正方形棋盘的边长    bool ONE, NUM, ALL;  // 由于只有一个递归函数,三个变量用于区分是哪一个问题    bool ONE_FINISH;  // 判断只返回一个解的问题是否已经解决    int num;  // 所有解的个数    vector<vector<char> > oneAns;  // 一个解    vector<vector<vector<char> > > allAns;  // 所有解    Queen() {        QChar = 'Q';        BChar = '.';        ONE = NUM = ALL = ONE_FINISH = false;    }    void changeChar(char q, char b) {  // 可以改变代表皇后和空白的字符        QChar = q;        BChar = b;    }    void makeBoard(int n) {  // 为接下来的操作开辟空间        N = n;        q_in_row = new int[N];        col_free = new bool[N];        up_free = new bool[2 * N - 1];        down_free = new bool[2 * N - 1];        for (int i = 0; i < N; i++) q_in_row[i] = col_free[i] = true;        for (int i = 0; i < 2 * N - 1; i++) up_free[i] = down_free[i] = true;    }    void deleteBoard() {  // 删除已经开辟的空间        delete []q_in_row;        delete []col_free;        delete []up_free;        delete []down_free;    }    void construct_solution() {  // 构造法,通过N皇后问题的规律总结而来,出自http://poj.org/problem?id=3239        int row = 0;        if (N % 6 != 2 && N % 6 != 3) {            if (N % 2 == 0) {                for (int i = 2; i <= N; i += 2) q_in_row[row++] = i - 1;                for (int i = 1; i <= N - 1; i += 2) q_in_row[row++] = i - 1;            } else {                for (int i = 2; i <= N - 1; i += 2) q_in_row[row++] = i - 1;                for (int i = 1; i <= N; i += 2) q_in_row[row++] = i - 1;            }        } else {            if (N % 2 == 0) {                if ((N / 2) % 2 == 0) {                    for (int i = N / 2; i <= N; i += 2) q_in_row[row++] = i - 1;                    for (int i = 2; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;                    for (int i = N / 2 + 3; i <= N - 1; i += 2) q_in_row[row++] = i - 1;                    for (int i = 1; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;                } else {                    for (int i = N / 2; i <= N - 1; i += 2) q_in_row[row++] = i - 1;                    for (int i = 1; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;                    for (int i = N / 2 + 3; i <= N; i += 2) q_in_row[row++] = i - 1;                    for (int i = 2; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;                }            } else {                if ((N / 2) % 2 == 0) {                    for (int i = N / 2; i <= N - 1; i += 2) q_in_row[row++] = i - 1;                    for (int i = 2; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;                    for (int i = N / 2 + 3; i <= N - 2; i += 2) q_in_row[row++] = i - 1;                    for (int i = 1; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;                    q_in_row[row++] = N - 1;                } else {                    for (int i = N / 2; i <= N - 2; i += 2) q_in_row[row++] = i - 1;                    for (int i = 1; i <= N / 2 - 2; i += 2) q_in_row[row++] = i - 1;                    for (int i = N / 2 + 3; i <= N - 1; i += 2) q_in_row[row++] = i - 1;                    for (int i = 2; i <= N / 2 + 1; i += 2) q_in_row[row++] = i - 1;                    q_in_row[row++] = N - 1;                }            }        }        write_in(oneAns);    }    vector<vector<char> > Return_an_ans(int n) {  // 返回一个解        makeBoard(n);        if (n > 3) {            construct_solution();        } else {            ONE = true;            dfs(0);        }        deleteBoard();        return oneAns;    }    int Return_all_ans_num(int n) {  // 返回所有解的个数        makeBoard(n);        NUM = true;        num = 0;        dfs(0);        deleteBoard();        return num;    }    vector<vector<vector<char> > > Return_all_ans(int n) {  // 返回所有解        makeBoard(n);        ALL = true;        dfs(0);        deleteBoard();        return allAns;    }    void write_in(vector<vector<char> > & a) {  // 写入一个解        a.resize(N);        for (int i = 0; i < N; i++) {            a[i].resize(N);            for (int j = 0; j < N; j++) {                if (q_in_row[i] == j) a[i][j] = QChar;                else a[i][j] = BChar;            }        }    }    void dfs(int now) {  // 深搜到每一个解        if (now == N) {  // 如果能到这步说明找到了一个合适解            if (ONE) {  // 如果只要求一个                ONE_FINISH = true;                write_in(oneAns);                return;            }            if (NUM) {  // 如果求的是数目                num++;                return;            }            if (ALL) {  // 如果要求所有解                vector<vector<char> > a;                write_in(a);                allAns.push_back(a);                return;            }        }        for (int col = 0; col < N; col++) {  // 对于每一列遍历            if (col_free[col] && up_free[now + col] && down_free[now - col + N - 1]) {  // 如果找到合适位置                q_in_row[now] = col;  // 写入列号                col_free[col] = up_free[now + col] = down_free[now - col + N - 1] = false;  // 为下一步划定限制                dfs(now + 1);                if (ONE && ONE_FINISH) return;                col_free[col] = up_free[now + col] = down_free[now - col + N - 1] = true;  // 重置以免影响其他深搜            }        }    }};int main() {    std::cout.sync_with_stdio(false);    Queen q;    int caseNum;    cin >> caseNum;    while (caseNum--) {        int temp;        cin >> temp;        cout << temp;        vector<vector<char> > ans = q.Return_an_ans(temp);        for (int i = 0; i < temp; i++) {            for (int j = 0; j < ans[i].size(); j++) {                if (ans[i][j] == 'Q') {                    cout << " " << j;                    break;                }            }        }        cout << endl;    }    return 0;}                                 


0 0
原创粉丝点击