一个月之前,数据结构看完了深度和广度搜索,做这个搜索题目的时候,总是超时,后来才知道可以进行剪枝可以判断是否可以在T的时间内到达指定的地点。
现在重新做了这道题,看了百度百科的奇偶剪枝,发现一下子就可以理解了,原来这个没有那么的难。这也让我明白了,有时候做题的时候,解决不了,或者看不懂的时候,可以先放一放,等以后再来做,思路拓宽了,没有仅限在这道题中,或许那时候你就可以做出来了,做题的心态和思路很重要。
奇偶剪枝,在百度百科中有详细的讲解和证明,这里不多讲了。
http://baike.baidu.com/link?url=WXb7wOhgR-b_EYehE5y6H0tmdAl_mi8-tBGcMoX6SkAU_l6y5ti9dedLlNoYzreX1tpgCb4mp_xHlEiXY7l6_q
杭电1010这一题的题目大意是:一条狗进入一个神奇的迷宫,一秒走一个空白的地方,狗走过的地方会消失,也就是说狗不能往回走,门在T秒之后打开,且打开很短的时间,狗只有在T秒的时候到达才能离开。
下面是AC的代码:
# include
# include
using namespace std;
char str[10][10];
int m, n, t;
int ex, ey;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
bool if_yes; //布尔变量,来判断是否可以到达
int main()
{
void dfs(int x, int y, int count);
while(cin >> m >> n >> t && m != 0 && n != 0 && t != 0)
{
int i, j, sx, sy, wall_count = 0;
getchar();
if_yes = false;
memset(str, '\0', sizeof(str));
for(i = 0; i < m; i++)
{
for(j = 0; j < n; j++)
{
cin >> str[i][j];
if(str[i][j] == 'S' || str[i][j] == 's') //找到起点
{
sx = i;
sy = j;
str[i][j] = 'X'; //起点变成墙,避免搜索的时候进来,
}
else if(str[i][j] == 'D' || str[i][j] == 'd') //找到终点
{
ex = i;
ey = j;
}
else if(str[i][j] == 'X' || str[i][j] == 'x') //数墙有多少
wall_count++;
}
getchar();
}
if(n * m - wall_count >= t) //空白的地方必须大于等于时间,这个很明确的,不然到不了,进行剪枝
{
dfs(sx, sy, 0);
}
if(if_yes)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
return 0;
}
void dfs(int x, int y, int count)
{
if(ex == x && ey == y && count == t) //找到了
{
if_yes = true;
return;
}
int a = (t - count) - (abs(x - ex) + abs(y - ey)); //算出偏移路径
if(a % 2 == 1 || a < 0) //如果是奇数或者小于0, 进行剪枝
{
if_yes = false;
return;
}
for(int i = 0; i < 4; i++) //四个方向进行搜索
{
if(x + dx[i] < 0 || x + dx[i] > m - 1 || y + dy[i] < 0 || y + dy[i] > n - 1) //越出边界的情况
continue;
if(str[x + dx[i]][y + dy[i]] != 'X' && str[x + dx[i]][y + dy[i]] != 'x') //如果该位置可以走
{
str[x + dx[i]][y + dy[i]] = 'X'; //变成墙,避免重新走过
dfs(x + dx[i], y + dy[i], count + 1); //递归进行搜索
str[x + dx[i]][y + dy[i]] = '.'; //变回来
}
if(if_yes)
break;
}
}
参考博客:
http://blog.csdn.net/mylovepanning/article/details/8118165