zoukankan      html  css  js  c++  java
  • 蓝桥杯—BASIC-27 2n皇后问题(DFS)

    问题描述
      给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,
    使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、
    同一列或同一条对角线上。问总共有多少种放法?n小于等于8。
    输入格式
      输入的第一行为一个整数n,表示棋盘的大小。
      接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,
    表示对应的位置不可以放皇后。
    输出格式
      输出一个整数,表示总共有多少种放法。
    样例输入
    4
    1 1 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
    样例输出
    2
    样例输入
    4
    1 0 1 1
    1 1 1 1
    1 1 1 1
    1 1 1 1
    样例输出
    0

    分析:回溯法

    代码

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int MAX_N = 8;
    int n;
    int ans = 0;
    int c = 0; 
    int a[MAX_N][MAX_N];
    int res1[3][MAX_N*2];//记录列,左对角线,右对角线是否有相同的皇后 
    int res2[3][MAX_N*2];//记录列,左对角线,右对角线是否有相同的皇后 
    void solve2(int cur) {
        if(cur == n) { c++; return; }
        for(int j = 0; j < n; j++) {
            if(a[cur][j] && !res2[0][j] && !res2[1][cur+j] && !res2[2][n+cur-j]) {
                res2[0][j] = 1; res2[1][cur+j] = 1; res2[2][n+cur-j] = 1;
                solve2(cur+1);
                res2[0][j] = 0; res2[1][cur+j] = 0; res2[2][n+cur-j] = 0;
            }
        }
        return;
    }
    void solve1(int cur) {
        if(cur == n) {
            c = 0;
            solve2(0);
            ans += c;   
            return;
        }
        for(int j = 0; j < n; j++) {
            if(a[cur][j] && !res1[0][j] && !res1[1][cur+j] && !res1[2][n+cur-j]) {
                a[cur][j] = 0;
                res1[0][j] = 1; res1[1][cur+j] = 1; res1[2][n+cur-j] = 1;
                solve1(cur+1);
                a[cur][j] = 1;
                res1[0][j] = 0; res1[1][cur+j] = 0; res1[2][n+cur-j] = 0;
            }
        }
        return;
    }
    int main() {
        while(scanf("%d", &n) == 1) {
            ans = 0;
            for(int i = 0; i < n; i++)
                for(int j = 0; j < n; j++) 
                    scanf("%d", &a[i][j]);
             solve1(0);
             printf("%d
    ", ans);
        }
        return 0;
    }

    以下为蓝桥杯测试系统的五组测试数据

    input 1

    3
    1 1 0 
    1 1 1 
    1 1 0 

    output1

    0

    input2

    4
    1 1 1 1 
    1 0 1 1 
    1 1 1 1 
    1 1 1 1 

    output2

    2

    input 3

    5
    1 1 1 1 1 
    1 0 1 1 1 
    1 1 1 1 1 
    1 0 1 1 1 
    1 1 1 1 1 

    output3

    12

    input4

    6
    1 1 1 1 1 1 
    1 1 1 1 1 1 
    1 1 1 1 1 1 
    1 1 1 1 1 1 
    1 1 1 1 1 1 
    1 1 1 1 1 1 

    output4

    12

    input5

    7
    1 1 1 1 1 1 0 
    1 1 1 1 1 1 1 
    1 1 1 1 1 1 1 
    1 1 1 1 1 1 1 
    1 1 1 1 1 1 1 
    1 1 1 1 1 1 1 
    1 1 1 1 1 1 1 

    output5

    408

    作者:kindleheart
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    操作系统设计与实现 读笔(2)
    操作系统设计与实现 读笔(1)
    C++历史及优点
    套接字Socket——TCP、UDP通信
    Unix环境_进程管理
    Unix环境_信号处理机制
    排序算法汇总
    TCP/IP体系结构
    数据库模式——三级模式两级映像
    杨辉三角形的递归实现
  • 原文地址:https://www.cnblogs.com/kindleheart/p/8417511.html
Copyright © 2011-2022 走看看