• 【回溯】n皇后问题


    问题 U: 【回溯】n皇后问题

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 4  解决: 4
    [提交][状态][讨论版]

    题目描述

    在一个国际象棋棋盘上,放置n个皇后(n<10),使她们相互之间不能进攻。求出所有布局。

    输入

    一个整数n(0<n<10)

    输出

    每行输出一种方案,每种方案顺序输出皇后所在的列号,各个数之间用空格分隔。

    样例输入

    4
    

    样例输出

        2    4    1    3
        3    1    4    2

    解题思路:一上午都没做出题来,开始看回溯了,总是不能理解,今下午看刘汝佳的算法竞赛,上面有n皇后问题,讲解地很细致。
      看完后然后终于能敲出代码了。
      c[i]保存第i行的列,比如 3 2 4 0 5 ,3表示第零行放在第三列,2表示第一行放在第2列,4表示第二行放在第4列,0表示第三行放在第0列...(从0开始)
      函数backtrack(int line)需要设置结束条件,当行数==n时,就可以输出c[i]保存的结果了。
      
      当没到结束条件时,就开始从i到n遍历一遍,i到n指每一列,然后用函数 condition(line,i) 判断第line行,i列是否可以放皇后。
      在 condition(line,i) 里面有个v[3][2n]数组, v[0][],v[1][],v[2],分别表示第i列,副对角线,主对角线是否已经有皇后放置。
      

      line+i和line-i只要有一个是1,就说明这个位置的主对角线,或副对角线上已经有皇后了,便不能再放了,但由于line-i可能为负数,便用+n来保存。

      另外要注意backtrack(line+1)之后吧这三个数组的值还原成0;


    代码:
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    int n;
    int c[15]={0};
    int v[3][25]={0};
    
    bool condition(int line,int i){
        return !v[0][i] && !v[1][line+i] && !v[2][line-i+n];
    }
    
    void backtrack(int line){
        if(line==n){
            for(int i=0;i<n;i++){
                printf("    %d",c[i]+1);
            }
            printf("
    ");
        }else{
            for(int i=0;i<n;i++){  //分别试试放哪一列上
                if(condition(line,i)){
                    c[line]=i;
                    v[0][i]=v[1][line+i]=v[2][line-i+n]=1;
                    backtrack(line+1);
                    v[0][i]=v[1][line+i]=v[2][line-i+n]=0;
                }
            }
        }
    }
    
    int main()
    {
    
        scanf("%d",&n);
        backtrack(0);
        return 0;
    }
     
  • 相关阅读:
    T4设计时模板调试
    MVC开发T4代码生成之一文本模板基础
    经典选项卡
    IE 调试工具 Utilu IE Collection:IE5.5、6.0、7.0, 8.0…各版本浏览器兼容性测试工具
    滚动读行!
    自定义标签的用法、支持IE6
    jQuery 参数传递例子
    IMG在IE6下不能HOVER的解决办法!
    点击渐变弹出层
    操作滚动条滚动到指定位置
  • 原文地址:https://www.cnblogs.com/TWS-YIFEI/p/5744585.html
Copyright © 2020-2023  润新知