【一个递归问题】为什么本地测试多组数据正确,提交后是WA?

Bohan_Li 2016-10-12 01:06:24
3:走出迷宫

总时间限制: 1000ms 内存限制: 65536kB
描述
当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。
假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路。

输入
第一行是两个整数n和m(1<=n,m<=100),表示迷宫的行数和列数。
接下来n行,每行一个长为m的字符串,表示整个迷宫的布局。字符'.'表示空地,'#'表示墙,'S'表示起点,'T'表示出口。
输出
输出从起点到出口最少需要走的步数。
样例输入
3 3
S#T
.#.
...
样例输出
6
这是POJ上的一道题目,我进行了样例测试,自己又写了几组数据测试,输出结果均正确,但是提交后就是WA,这是为啥捏……

代码如下

#include<iostream>
using namespace std;
int m = 0, n = 0;
bool b[100][100];
int r[100][100];//用于记录每个点到终点的最短距离
char p[100][100] = { 0 };
int min(int a1, int a2, int a3, int a4)//在四个方向点的返回值中取最小值,过滤掉-1和-2的两种情况,只取正整数最小值
{
int mi = 10000000;
if (a1 >= 0 && a1 < mi)
{
mi = a1;
}
if (a2 >= 0 && a2 < mi)
{
mi = a2;
}
if (a3>= 0 && a3 < mi)
{
mi = a3;
}
if (a4 >= 0 && a4 < mi)
{
mi = a4;
}
return mi;//如果四个方向的值均不能向前也就是说该点成为死点,返回值将会是10000000,问题会不会出在这里?
}
int f(int u, int v)//输入一个点的u,v坐标,求该点到终点的最少步数
{
b[u][v] = 1;//首先将该点标记为走过
if (p[u][v] == 'T')//判断是否到达终点
{
return 0;//已到达,返回0步
r[u][v] = 0;//记录到达终点的步数
}

else if (r[u][v] != -1)//为到达终点,如果这个点已经测试过最近距离,直接返回该距离
{
return r[u][v];
}

else//都没有,开始递归
{
int s1, s2, s3, s4;//记录四个方向上点各走几步可以到达终点

if (u== 0 || p[u - 1][v] == '#')//向上
{
s1 = -1;//-1代表该方向碰壁/不能走
}
else if (b[u - 1][v] == 1)
{
s1=-2;//-2代表该方向是来的方向
}
else
{
s1 = f(u - 1, v);//返回由该方向上的下一个点到达终点的最短步数
b[u - 1][v] = 0;//返回后,将该方向下一个点标记为未走过
}


if (v== 0 || p[u][v-1] == '#')//向左
{
s2 = -1;
}
else if (b[u ][v-1] == 1)
{
s2 = -2;
}
else
{
s2 = f(u, v-1);
b[u][v - 1] = 0;
}


if (u == n-1 || p[u + 1][v] == '#')//向下
{
s3 = -1;
}
else if (b[u + 1][v] == 1)
{
s3 = -2;
}
else
{
s3 = f(u + 1, v);
b[u + 1][v] = 0;
}


if (v==m-1 || p[u ][v+1] == '#')//向右
{
s4 = -1;
}
else if (b[u ][v+1] == 1)
{
s4 = -2;
}
else
{
s4 = f(u , v+1);
b[u][v + 1] = 0;
}

int step = min(s1, s2, s3, s4) + 1;//在返回的四个值中取最小值,+1为该点到终点的最少步数
r[u][v] = step;//记录该点到终点的最少步数
return step;//返回该点到终点的最少步数

}
}
int main()
{

for (int i = 0; i < 100; i++)//初始化记录数组r[100][100]
{
for (int j = 0; j < 100; j++)
{
r[i][j]=-1;
}
}
cin >> n >> m;
int a = 0, b = 0;
int k = 0;
while (k < n)
{
for (int i = 0; i < m; i++)
{
cin >> p[k][i];
if (p[k][i] == 'S')
{
a = k;
b = i;
}
}
k++;
}

cout << f(a, b) << endl;

return 0;
}
...全文
440 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
Bohan_Li 2016-10-14
  • 打赏
  • 举报
回复
引用 2 楼 FancyMouse 的回复:
3 4 .... ..#. T..S
后来检查觉得在递归求解的时候的递归顺序好像有点跟预期的不太符合……但是找不到问题出在哪里,请问下这整套思路有什么问题吗?
#include<iostream>
using namespace std;
int m = 0, n = 0;
bool b[100][100];
int r[100][100];//用于记录每个点到终点的最短距离
char p[100][100] = { 0 };
int min(int a1, int a2, int a3, int a4)//在四个方向点的返回值中取最小值,过滤掉-1和-2的两种情况,只取正整数最小值,并将最后结果+1
{
	int mi = 10000000;
	if (a1 >= 0 && a1 < mi)
	{
		mi = a1;
	}
	if (a2 >= 0 && a2 < mi)
	{
		mi = a2;
	}
	if (a3 >= 0 && a3 < mi)
	{
		mi = a3;
	}
	if (a4 >= 0 && a4 < mi)
	{
		mi = a4;
	}
	return mi;
}
int f(int u, int v)//输入一个点的u,v坐标,求该点到终点的最少步数
{

	b[u][v] = true;//首先将该点标记为走过

	if (p[u][v] == 'T')//判断是否到达终点
	{
		b[u][v] = 0;//撤销记录
		r[u][v] = 0;//记录到达终点的步数
		return 0;//已到达,返回0步
	}

	else if (r[u][v] != -1)//如果这个点已经测试过最近距离,直接返回该距离
	{
		b[u][v] = 0;//撤销记录
		return r[u][v];
	}

	else//都没有,开始递归
	{
		int s1, s2, s3, s4;//记录四个方向上点各走几步可以到达终点

		if (u <1 || p[u - 1][v] == '#')//向上
		{
			s1 = -1;//-1代表该方向碰壁/不能走
		}
		else if (b[u - 1][v] == 1)
		{
			s1 = -2;//-2代表该方向是来的方向
		}
		else
		{
			s1 = f(u - 1, v);//返回由该方向上的下一个点到达终点的最短步数
		}

		if (v <1 || p[u][v - 1] == '#')//向左
		{
			s2 = -1;
		}
		else if (b[u][v - 1] == 1)
		{
			s2 = -2;
		}
		else
		{
			s2 = f(u, v - 1);
		}


		if (u >n-2 || p[u + 1][v] == '#')//向下
		{
			s3 = -1;
		}
		else if (b[u + 1][v] == 1)
		{
			s3 = -2;
		}
		else
		{
			s3 = f(u + 1, v);
		}


		if (v >m-2|| p[u][v + 1] == '#')//向右
		{
			s4 = -1;
		}
		else if (b[u][v + 1] == 1)
		{
			s4 = -2;
		}
		else
		{
			s4 = f(u, v + 1);
		}

		int step = min(s1, s2, s3, s4)+1;//在返回的四个值中取最小值,+1为该点到终点的最少步数
		r[u][v] = step;//记录该点到终点的最少步数
		b[u][v] = 0;//撤销记录
		return step;//返回该点到终点的最少步数

	}
}
int main()
{

	for (int i = 0; i < 100; i++)//初始化记录数组r[100][100]
	{
		for (int j = 0; j < 100; j++)
		{
			r[i][j] = -1;
		}
	}
	cin >> n >> m;
	int a = 0, b = 0;
	int k = 0;
	while (k < n)
	{
		for (int i = 0; i < m; i++)
		{
			cin >> p[k][i];
			if (p[k][i] == 'S')
			{
				a = k;
				b = i;
			}
		}
		k++;
	}
	cout << f(a, b) << endl;

	return 0;
}
FancyMouse 2016-10-12
  • 打赏
  • 举报
回复
3 4 .... ..#. T..S
Bohan_Li 2016-10-12
  • 打赏
  • 举报
回复
关于边缘数据,我实在是想不出有什么边缘了,m=n=1?没有可行路径?但是这样的情况该输出什么题目根本没有提过啊

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧