2301_79745513 2025-01-11 18:01 采纳率: 0%
浏览 8

n皇后问题求解!help!刚开始学实在不明白

题目描述
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。

要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放 k 个棋子的所有可行的摆放方案数目 C。

输入格式
输入含有多组测试数据。

每组数据的第一行是两个正整数 n,k,用一个空格隔开,表示了将在一个 n∗n 的矩阵内描述棋盘,以及摆放棋子的数目。当为-1 -1时表示输入结束。

随后的 n 行描述了棋盘的形状:每行有 n 个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。

输出格式
对于每一组数据,给出一行输出,输出摆放的方案数目 C (数据保证 C<231)。

数据范围
n≤8,k≤n


#include<iostream>
using namespace std; 
char a[10][10];
int sl[10]={0};
int sh[10]={0};
int res=0;
int n,k;

void dfs(int x)//记录第几行 
{

    if(x==k+1)
    {
        res++;
        return;
    }
    for(int i=1;i<=n;i++)  //记录第几列 
{
    if(sh[i]==1)
    {
        continue;
    }
    for(int j=1;j<=n;j++)
    {
        if(a[i][j]=='#'&&sl[j]==0)
        {
            sh[i]=1;
            sl[j]=1;
            dfs(x+1);
            sl[j]=0;
            sh[i]=0;
        }
    }
}
}

int main()
{
    while(cin>>n>>k,n>0&&k>0)
    {
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            cin>>a[i][j]; 
        }
    }
    res=0;
    dfs(1);
    cout<<res<<endl;
    }
    return 0;
}

想问一下,我的代码如何避免,棋子重复出现在同一个位置上时,也计算总次数

  • 写回答

4条回答 默认 最新

  • 道友老李 JWE233286一种基于机器视觉的水表指针读数识别及修正的方法 专利发明者 2025-01-11 18:02
    关注
    让【道友老李】来帮你解答,本回答参考gpt编写,并整理提供,如果还有疑问可以点击头像关注私信或评论。
    如果答案让您满意,请采纳、关注,非常感谢!
    在代码中,可以在递归的部分加入条件判断,当某个位置已经被放置了棋子时,直接跳过该位置。修改后的代码示例如下:
    #include<iostream>
    using namespace std;
    char a[10][10];
    int sl[10]={0};
    int sh[10]={0};
    int res=0;
    int n,k;
    void dfs(int x) //记录第几行 
    {    
        if(x==k+1)    
        {
            res++;
            return;
        }    
        for(int i=1;i<=n;i++)  //记录第几列 
        {    
            if(sh[i]==1)    
            {
                continue;
            }    
            for(int j=1;j<=n;j++) 
            {
                if(a[i][j]=='#' && sl[j]==0)        
                {
                    if(a[i][j]=='.' || (i>1 && a[i-1][j]=='.') || (j>1 && a[i][j-1]=='.')) continue; // 加入判断条件,避免相邻位置重复放置
                    sh[i]=1;
                    sl[j]=1;
                    dfs(x+1);
                    sl[j]=0;
                    sh[i]=0;
                }
            }
        }
    }
    int main(){
        while(cin>>n>>k,n>0 && k>0)
        {    
            for(int i=1;i<=n;i++)    
            {
                for(int j=1;j<=n;j++)        
                {
                    cin>>a[i][j];
                }    
            }    
            res=0;
            dfs(1);
            cout<<res<<endl;
        }
        return 0;
    }
    

    在代码中,增加了判断条件 if(a[i][j]=='.' || (i>1 && a[i-1][j]=='.') || (j>1 && a[i][j-1]=='.')) continue;,这样当某个位置已经被放置了棋子时,就会跳过该位置,并不再继续计算。

    评论

报告相同问题?

问题事件

  • 创建了问题 1月11日