回溯经典(指定位置N皇后问题)

N皇后问题自不必多说,这道题的先行条件是在放置的时候已经指定了一个棋子的位置。

输入第一行为N,第二行为指定棋子的坐标(x,y);输出方案总数以及按字典序升序的各种方案。

思路:
首先是回溯,其次对待指定棋子有三种方法:

  1. 枚举所有情况,最后判断
  2. 在枚举到那一行的时候只让棋子下在指定的那一列
  3. 初始化vis数组时进行标记,同时跳过枚举x行和y列

第三种我没写出来,但很明显比前两种要快得多,第二种比第一种快了100多ms

代码如下:
第一种,耗时327ms:

#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
int n, x, y, tot = 0;
int vis[3][100], c[20];
int ans[1000000][20];

void search(int cur) {
    if (cur == n) {
        if (c[x] != y) return;
        memcpy(ans[tot], c,sizeof(c));
        tot++;
    }
    else for (int i = 0; i < n; i++) {
        if (!vis[0][i] && !vis[1][cur + i] && !vis[2][cur - i + n]) {
            c[cur] = i;
            vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 1;
            search(cur + 1);
            vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 0;
        }
    }
}

int main() {
    scanf("%d", &n);
    scanf("%d%d", &x, &y);
    x--; y--;
    search(0);
    printf("%d
", tot);
    for (int i = 0; i < tot; i++) {
        for(int j = 0; j < n; j++) {
            printf("%d ", ans[i][j] + 1);
        }
        printf("
");
    }
    return 0;
}

第二种,耗时221ms

#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
int n, x, y, tot = 0;
int vis[3][100], c[20];
int ans[1000000][20];

void search(int cur) {
    //if (cur == x) { c[cur] = y; search(cur + 1); return; }
    if (cur == n) {
        //if (c[x] != y) return;
        memcpy(ans[tot], c, sizeof(c));
        tot++;
    }
    else for (int i = 0; i < n; i++) {
        if (cur == x&&i != y)continue;
        if (!vis[0][i] && !vis[1][cur + i] && !vis[2][cur - i + n]) {
            c[cur] = i;
            vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 1;
            search(cur + 1);
            vis[0][i] = vis[1][cur + i] = vis[2][cur - i + n] = 0;
        }
    }
}

int main() {
    scanf("%d", &n);
    scanf("%d%d", &x, &y);
    x--; y--;

    search(0);
    printf("%d
", tot);
    for (int i = 0; i < tot; i++) {
        for (int j = 0; j < n; j++) {
            printf("%d ", ans[i][j] + 1);
        }
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/romaLzhih/p/9489818.html