下面是我创建的NQueen的代码。有一些操作,比如调用nqueen函数,然后从nqueen-〉调用backtrack,它会递归并将值“1”放在动态分配的数组“arr”上。问题是,由于我已经在main中初始化了变量“n”并将其传递到nqueen &从nqueen到backtrack,有时会打印最终创建的完整nqueen数组,“n”被传递给print函数。“n”的值在每个递归调用中都是递减的,在一些递归调用中是这样的,但是我没有提供递减操作。
这是主函数,调用nqueen func传递“n”=4-〉
int main(){
int n=4;
int** arr=new int*[n];
for(int i=0;i<n;i++){
arr[i]=new int[n];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j]=0;
}
}
print(arr,n);
int num=nqueen(arr, n);
cout<<num<<endl;
return 0;
}
这里是通过传递“arr”和“n”并调用backtrack()传递相同的“arr”和“n”调用的nqueen函数。但是现在n的值以某种方式改变了。
int nqueen(int** arr,int n){
int count=0;
for(int i=0;i<n;i++){
count+=backtrack(arr,i,n);
}
return count;
}
这是nqueen调用代码后的backtrack()代码
int backtrack(int** arr,int i,int n){
if(i==n) return 0;
int count=0;
for(int j=0;j<n;j++){
if(check(arr,i,j,n)==0){
arr[i][j]=1;
cout<<"\n"<<i<<" "<<j<<" "<<n<<endl;
print(arr,n);
i++;
count+=backtrack(arr,i,j);
i--;
arr[i][j]=0;
}
}
return count;
}
这是包含一些函数的整体代码,如打印和检查数组中的皇后对角线和侧边的“i”和“j”位置
#include<iostream>
using namespace std;
int nqueen(int** arr,int n);
void print(int** arr,int n);
int backtrack(int** arr,int i,int n);
int check(int** arr,int i,int j,int n);
int backtrack(int** arr,int i,int n){
if(i==n) return 0;
int count=0;
for(int j=0;j<n;j++){
if(check(arr,i,j,n)==0){
arr[i][j]=1;
cout<<"\n"<<i<<" "<<j<<" "<<n<<endl;
print(arr,n);
i++;
count+=backtrack(arr,i,j);
i--;
arr[i][j]=0;
}
}
return count;
}
int nqueen(int** arr,int n){
int count=0;
for(int i=0;i<n;i++){
count+=backtrack(arr,i,n);
}
return count;
}
int check(int** arr, int i,int j,int n){
/////check vertical horizontal
for(int k=0;k<n;k++){
if(arr[i][k]==1) return 1;
if(arr[k][j]==1) return 1;
}
/////check diagonal
int k=i,l=j;
while(k<n&&l<n){
if(arr[k][l]==1){
return 1;
}
k++;
l++;
}
k=i,l=j;
while(k>=0&&l>=0){
if(arr[k][l]==1){
return 1;
}
k--;
l--;
}
k=i,l=j;
while(k>=0&&l<n){
if(arr[k][l]==1){
return 1;
}
k--;
l++;
}
k=i,l=j;
while(k<n&&l>=0){
if(arr[k][l]==1){
return 1;
}
k++;
l--;
}
return 0;
}
void print(int** arr,int n){
cout<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<arr[i][j]<<" "<<i<<j<<" ";
}
cout<<endl;
}
}
int main(){
int n=4;
int** arr=new int*[n];
for(int i=0;i<n;i++){
arr[i]=new int[n];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
arr[i][j]=0;
}
}
print(arr,n);
int num=nqueen(arr, n);
cout<<num<<endl;
return 0;
}
如果有人可以检查并提供我的解决方案。谢谢!
1条答案
按热度按时间3phpmpom1#
Jarod42写道:
你调用backtrack(arr,i,j)...所以来自int backtrack(int**arr,int i,int n)的n将是j,但来自main的n不变。
你正在看“n”,这是另一个(=本地)“n”。因为你的递归调用。
但是如果我执行这个,我也会得到一个Segfault。你调用check函数,i的值为“4”。这将访问第行中具有无效偏移量的arr:
对于大小为4的数组,有效值仅从0到3。编辑:当然i是4,因为在递归调用之前,有
i++
,如果它被允许变得更高,没有任何检查。我真的不明白这段代码的目的是什么,所以也许检查i和j是否有效就足够了,如果不是,就停止。