小白第一次开通博客,只是想分享自己的想法,不管愚蠢与否,大神们勿喷
我很多算法都不会,我来解释一下里面几个函数。
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;
}