• ADV674 2n皇后问题(递归)


    问题描述

      给定一个n*n的棋盘,棋盘中有一些位置不能放皇后。现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行、同一列或同一条对角线上,任意的两个白皇后都不在同一行、同一列或同一条对角线上。问总共有多少种放法?n小于等于8。

    输入格式

      输入的第一行为一个整数n,表示棋盘的大小。
      接下来n行,每行n个0或1的整数,如果一个整数为1,表示对应的位置可以放皇后,如果一个整数为0,表示对应的位置不可以放皇后。

    输出格式

      输出一个整数,表示总共有多少种放法。

    思路

    递归求解。
    q[i] = j表示第i行放在第j列上
    当前i-1行都确定后,枚举第i行能放在哪个位置,放下后,递归到第i+1行。
    (i, j)能否放置的条件为1.这个位置不为0 2. 前i-1行没有放在第j列上的 3. 前i-1行没有和它一个对角线上的
    st[i][j] != 0 q[k] != j abs(q[k] - j) != abs(k - i) (1 <= k <= i - 1)
    题目中白皇后和黑皇后各放n个,先算出一共有多少种放置的方案,并且记录方案。再枚举任意两个方案,这两个方案的放置方法不能有重叠。

    #include <iostream>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    
    const int N = 10;
    int st[N][N];
    int q[N], n, cnt;
    vector<int> path[100];
    
    bool place(int i, int j)
    {
        if(!st[i][j])   return false;
        if(i == 1)  return true;
        for(int k = 1; k < i; k ++ )
        {
            if(q[k] == j || abs(k - i) == abs(q[k] - j))
                return false;
        }
        return true;
    }
    
    void queue(int i)   // 1~i-1已经摆放好
    {
        if(i > n)
        {
            for(int i = 1; i <= n; i ++ )
                path[cnt].push_back(q[i]);
            cnt ++;
            return;
        }
        for(int j = 1; j <= n; j ++ )   // 枚举第i行能放在哪一列
        {
            if(place(i, j))
            {
                q[i] = j;
                queue(i + 1);
                q[i] = 0;
            }
        }
    }
    
    int main()
    {
        cin >> n;
        for(int i = 1; i <= n; i ++ )
            for(int j = 1; j <= n; j ++ )
                scanf("%d", &st[i][j]);
        queue(1);
        if(cnt < 2) printf("%d", 0);
        else
        {
            int res = 0;
    
            for(int i = 0; i < cnt; i ++ )
                for(int j = 0; j < cnt; j ++ )
                {
                    if(i != j)
                    {
                        bool flag = true;
                        for(int k = 0; k < n; k ++ )
                            if(path[i][k] == path[j][k])
                            {
                                flag = false;
                                break;
                            }
                        if(flag)    res ++;
                    }
                }
            cout << res;
        }
        return 0;
    }
    
  • 相关阅读:
    LeetCode 282. Expression Add Operators (Hard,递归分治)
    LeetCode 279. Perfect Squares
    LeetCode 278. First Bad Version
    LeetCode 275. H-Index II
    工作笔记——使用Jest时遇到的一些问题
    RFC2616-HTTP1.1-Header Field Definitions(头字段规定部分—译文)
    RFC2616-HTTP1.1-Status Code(状态码规定部分—译文)
    RFC2616-HTTP1.1-Methods(方法规定部分—译文)
    RFC2616-HTTP1.1-Status Code(状态码规定部分—单词注释版)
    RFC2616-HTTP1.1-Methods(方法规定部分—单词注释版)
  • 原文地址:https://www.cnblogs.com/Hfolsvh/p/15963759.html
Copyright © 2020-2023  润新知