皇后问题

小白第一次开通博客,只是想分享自己的想法,不管愚蠢与否,大神们勿喷

我很多算法都不会,我来解释一下里面几个函数。

H()函数代表检查一个数组每行是不是有多余的数字,如果有1个数字或0个则返回1,否则返回0

L()函数代表检查一个数组每列是不是有多余的数字,如果有1个数字或0个则返回1,否则返回0

X()函数代表检查一个数组任意一个位置的对角是不是有多余的数字,

1)如果v[i][j]这个位置是1,那么这个位置斜向左,向右都不允许有其他数,都必须是0,这时返回1,否则返回0;

2)如果v[i][j]这个位置是0,那么斜向左,向右的数当中各自至多有一个数,这时返回1,否则返回0,

dfs这个函数就是深度递归,

for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)
            if(i>k){
                if(v[i][j]==0){
                     v[i][j]=1;
                     dfs(num+1,i,j);
                     v[i][j]=0;
                 }    
            }else if(i==k && j>t){
                if(v[i][j]==0){
                     v[i][j]=1;
                     dfs(num+1,i,j);
                     v[i][j]=0;
                 }    
            }   
这段代码里面的if else是什么意思呢,代表接下来的一次递归必须选择这个数v[i][j]以下的数,不能选贼它前面的数,否则就会出现重复,如果没有if else,我算出来有1200个数,其实答案是10,课件有多少重复的,读者也需要有自己的思考,我也是想了很久,因为我很笨,加油

#include<iostream>

using namespace std;
int count=0;
int n=5;
int v[5][5];
int a[5][5];
//判断行
int H(){
    int flag=0;                                
    for(int i=0;i<5;i++){                        
        for(int j=0;j<5;j++){            
            if(v[i][j]==1){                            
                flag++;                                    
                if(flag==2){
                    return 0;
                }
                    
            }
        }
        flag=0;
    }
    return 1;
}
//判断列
int L(){
    int flag=0;
    for(int i=0;i<5;i++){
        for(int j=0;j<5;j++){
            if(v[j][i]==1){
                flag++;
                if(flag==2)
                    return 0;
            }
        }
        flag=0;
    }
    return 1;
}
//判断斜线
int X(int h,int k){
    int h1=h,h2=h,h3=h,h4=h;
    int k1=k,k2=k,k3=k,k4=k;
    int flag1=0,flag2=0;
    if(v[h][k]==1){
        while(--h1>=0 && --k1>=0){
            if(v[h1][k1]==1)
                return 0;
        }
        while(++h2<5 && --k2>=0){
            if(v[h2][k2]==1)
                return 0;
        }
        while(--h3>=0 && ++k3<5){
            if(v[h3][k3]==1)
                return 0;
        }while(++h4<5 && ++k4<5){
            if(v[h4][k4]==1)
                return 0;
        }
    }else{
        while(--h1>=0 && --k1>=0){
            if(v[h1][k1]==1){
                flag1++;
                if(flag1==2)
                    return 0;
            }
                
        }
        while(++h2<5 && --k2>=0){
            if(v[h2][k2]==1){
                flag2++;
                if(flag2==2)
                    return 0;
            }
        }
        while(--h3>=0 && ++k3<5){
            if(v[h3][k3]==1){
                flag2++;
                if(flag2==2)
                    return 0;
            }
        }
        while(++h4<5 && ++k4<5){
            if(v[h4][k4]==1){
                flag1++;
                if(flag1==2)
                    return 0;
            }
        }
    }
    return 1;
}
void dfs(int num,int k,int t){
    if(num>n){
        int flag=0;
        for(int p=0;p<5;p++)
            for(int q=0;q<5;q++){
                if(X(p,q)==0)
                    return ;
                if(p==4 && q==4)
                    flag=1;
            }
            
        if(H()==0 || L()==0 || flag==0)
            return ;
        if(H()==1 && L()==1 && flag==1){
            for(int i1=0;i1<5;i1++){            
                for(int j1=0;j1<5;j1++)
                    cout<<v[i1][j1]<<" ";
                    cout<<endl;
            }
            
            cout<<endl;
            count++;
            return ;
        }            
    }
    for(int i=0;i<5;i++)
        for(int j=0;j<5;j++)
            if(i>k){
                if(v[i][j]==0){
                     v[i][j]=1;
                     dfs(num+1,i,j);
                     v[i][j]=0;
                 }    
            }else if(i==k && j>t){
                if(v[i][j]==0){
                     v[i][j]=1;
                     dfs(num+1,i,j);
                     v[i][j]=0;
                 }    
            }            
}
int main(){    
    dfs(1,-1,-1);
    cout<<count;

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值