zoukankan      html  css  js  c++  java
  • 回溯经典(指定位置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;
    }
  • 相关阅读:
    vss的ss.ini丢失或损坏导致的vss无法登录错误
    NHibernate各种数据库连接参数文件配置方法说明
    oracle操作语句
    企业微信群聊机器人发送本地图片
    securecrt 或xshell 转发80端口
    SecureCRT 或 XSHELL 转发 X11 图形化GUI
    Windows 创建 .gdbinit 提示必须键入文件名
    vscode C++ 程序 windows
    vscode C++ 程序 windows
    解决source insight 4.0 不识别.cc文件的问题
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9489818.html
Copyright © 2011-2022 走看看