• 回溯经典(指定位置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;
    }
  • 相关阅读:
    paip.调用GUI接口.
    paip.按键替换映射总结
    paip.IIS 7.5 应用程序池,应用程序以及虚拟目录的存储位置
    paip.android 手机输入法制造大法
    paip.设置鼠标灵敏度API
    paip.系统无法在消息文件中为 Application 找到消息号为 0x2350 的消息文本。服务器存储空间不足,无法处理此命令
    paip.DEVSUIT WEB .NET ASPX网站打开慢的原因
    paip.动画透明淡入淡出窗口之重绘性能
    PAIP。JS调用DLL的解决方案
    paip.输入法编程四级非常用汉字汉字1000个
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9489818.html
Copyright © 2020-2023  润新知