• 2n皇后问题


    问题描述
      给定一个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
     
    思路:首先要先知道n皇后问题怎么解决,然后再解决2n皇后问题。
    2n皇后解法:先把一种皇后放好,再放另一种皇后。
    代码实现:
    #include <iostream>
    #include <cmath>
    #define MAX 11
    
    using namespace std;
    
    int n;
    int wc[MAX],bc[MAX];
    int mmap[MAX][MAX];
    int res=0;
    
    void bdps(int num)
    {
        for(int i=0;i<num-1;i++)
        {
            if(bc[i]==bc[num-1]||(abs(num-1-i)==abs(bc[num-1]-bc[i])))
                return;
        }
        if(num>=n)
        {
            res++;
            return;
        }
    
        for(int i=0;i<n;i++)
        {
            if(mmap[num][i]&&wc[num]!=i)
            {
                bc[num]=i;
                //if(check(num))    //本来应该在这里检查num放的位置是否合法,但是也可以放到递归地最开始位置,因为进入递归地是num+1,所以上面判断的时候值是num-1.
                    bdps(num+1);
            }
    
        }
    }
    void wdps(int num)
    {
        for(int i=0;i<num-1;i++)
        {
            if(wc[i]==wc[num-1]||(abs(num-1-i)==abs(wc[num-1]-wc[i])))
                return;
        }
        if(num>=n)
        {
            bdps(0);
            return;
        }
    
        for(int i=0;i<n;i++)
        {
            if(mmap[num][i])
            {
                wc[num]=i;
                //if(check(num))    //本来应该在这里检查num放的位置是否合法,但是也可以放到递归地最开始位置,因为进入递归地是num+1,所以上面判断的时候值是num-1.
                    wdps(num+1);
            }
    
        }
    }
    int main()
    {
        while(cin>>n&&n)
        {
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                    cin>>mmap[i][j];
            }
            res=0;
            wdps(0);
            cout<<res<<endl;
        }
        return 0;
    }
    

      

    人生如修仙,岂是一日间。何时登临顶,上善若水前。
  • 相关阅读:
    论抱怨
    GitHub开源的10个超棒后台管理面板
    RESTful API 最佳实践
    理解RESTful架构
    redis 数据类型详解 以及 redis适用场景场合
    redis的应用场景 为什么用redis
    composer install 出现的问题
    什么是反向代理
    电脑 DNS纪要
    ajax请求处理概要
  • 原文地址:https://www.cnblogs.com/f-society/p/6702601.html
Copyright © 2020-2023  润新知