我的代码给了我运行时错误。我不知道该如何解决? 它甚至不适用于较小的矩阵4 X 4。问题的矩阵大小不超过20 x 20。
代码:
#include <iostream>
using namespace std;
int a[20][20];
bool findpath(int ar[][20],int i,int j,int size)
{
if (ar[i][j]==0 || i>(size-1) || j>(size-1) || i<0 || j<0)
return false;
if (ar[i][j]==2)
return true;
if ((findpath(ar,i+1,j,size)) || (findpath(ar,i,j+1,size))
|| (findpath(ar,i-1,j,size)) || (findpath(ar,i,j-1,size)))
return true;
return false;
}
int main() {
int t;
cin>>t;
while(t--)
{ int n;
cin>>n;
int r,c;
//size = n;
for(int i =0 ;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>a[i][j];
if (a[i][j]==1)
{ r=i;
c=j;
}
}
}
//cout<<r<<c;
bool b = findpath(a,r,c,n);
if (b)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
输入:
1
4
3 0 0 0 0 3 3 0 0 1 0 3 0 2 3 3
输出:
YES
但是我得到Segmentation Fault (SIGSEGV)
答案 0 :(得分:1)
检查对语句if (ar[i][j]==0 || i>(size-1) || j>(size-1) || i<0 || j<0)
的求值顺序。即使i
超出范围或j
超出范围,您也将访问ar [i] [j]来评估第一个表达式。顺序应如此,以便在if
条件下发生短路时,您是安全的/不会导致不确定的行为,例如:
if (i < 0 || i >= size || j < 0 || j >= size || ar[i][j]==0)
。现在,如果i < 0
陷入僵局,则无需检查其余部分,并且不评估ar[i][j]
。
正如您提到的那样,这是行不通的,下面是一个有效的版本,我将向您解释。首先,我将您的C样式数组更改为向量,而是使用它们来获取行和列的大小。我还从用户中删除了您的输入,您可以在以后添加这些输入,并有助于使问题保持简单。
#include <vector>
bool findpath(vector<vector<int>>ar,int i,int j,vector<vector<int>>& visited)
{
if (i < 0 || i >= ar.size() || j < 0 || j >= ar[0].size() || ar[i][j] == 0 || visited[i][j]) return false;
if (ar[i][j]==2) return true;
visited[i][j] = true;
if(findpath(ar,i+1,j,visited) || findpath(ar,i,j+1,visited) || findpath(ar,i-1,j,visited) || findpath(ar,i,j-1,visited)) return true;
visited[i][j] = false;
return false;
}
int main() {
const int rows = 3;
const int cols = 3;
vector<vector<int>> arr = {{ 0 , 3 , 2 },
{ 3 , 3 , 0 },
{ 1 , 3 , 0 }};
vector<vector<int>> visited(rows,vector<int>(cols,false));
bool b = findpath(arr,1,1,visited);
if (b)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
在主要功能中,我仅使用vector<vector<int>>
来描述您发布的链接中的迷宫。在下面的示例中,i
和j
是1
和1
的起点。还有一个visited
二维数组,与迷宫相同。这样可以通过标记已经覆盖的斑点来阻止您进行无限递归,如果无法解决,您可以将vector[i][j] = false
设置为回溯。最后,如果您的安排中的任何一项返回有效结果,我们将返回否则,我们将仅返回false。
您可以观看此演示live here
您还提到1
是起点。在示例中,我已经从1
开始。您可以在main中添加一个循环,以便首先找出起点的坐标。同样,这应该足以使您前进。