Tempter of the Bone
翻译:
暑假的时候,小明和朋友去迷宫中寻宝。然而,当他拿到宝贝时,迷宫开始剧烈震动,他感到地面正在下沉,他们意识到这是一个陷阱!他们想尽一切办法逃出去。
迷宫是一个大小为 N*M 的长方形,迷宫中有一扇门。一开始,门是关着的,他会在第 t 秒的时间打开。因为,小明和朋友必须在第 t 秒到大门口。每一秒,他都可以向上下左右四个方向移动一个点。一旦他移动了,他刚才所在的点就消失,(这意味着他不能回到他已经走过的点)。他不能在一个点上停留超过一秒,并且不能走障碍点。小明和朋友能安全的逃出吗?
Input
输入由多个测试用例组成。每个测试用例的第一行包含三个整数 N、M 和 T ( 1 < N , M < 7 ; 0 < T < 50 ),分别表示迷宫的大小和门打开的时间。接下来的N行给出迷宫布局,每一行包含M个字符。下列字母分别表示:
“X”: 一堵墙,小明和朋友不能在上面停留
“S”: 起点
“D”: 门
“.”: 可以走的点
输入以 3 个 0 时结束。这个测试用例不需要处理。
Output
对于每组样例输出一行。
如果小明能够安全逃出,输出 “YES” ,否则输出 “NO”。
Sample Input
4 4 5
S.X.
…X.
…XD
…
3 4 5
S.X.
…X.
…D
0 0 0
Sample Output
NO
YES
代码实现:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
char Map[10][10]; //地图
int visit[10][10]; //储存数据标记
int n,m,t,endx,endy,flag; //n、m、结束坐标、标记
void dfs(int startx,int starty,int time) //开始坐标,时间
{
int dx,dy;
int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; //上下左右四个方向
if(flag) //***很重要,可以减少步骤,如果直接找到路线就直接return
{
return;
}
if(startx==endx&&starty==endy&&time==t)
{
flag=1;
return;
}
int temp=t-time-abs(endx-startx)-abs(endy-starty); //剪枝代码
if(temp<0||temp&1) //如果剩余的步数已经不足以走到出口,且必须是偶数,偶数-偶数=偶数,奇数-奇数=偶数
{
return;
}
for(int i=0;i<4;i++)
{
dx=startx+dir[i][0];
dy=starty+dir[i][1];
if(dx<0||dy>=m||dy<0||dx>=n)
{
continue;
}
if(Map[dx][dy]!='X'&&visit[dx][dy]==0)
{
visit[dx][dy]=1; //标记,判断能不能走
dfs(dx,dy,time+1);
if(flag) //找到就return
return;
visit[dx][dy]=0; //返回标记,方便下次寻找
}
}
return ;
}
int main()
{
int startx,starty,wall; //开始坐标、墙
while(cin>>n>>m>>t)
{
if(n==0&&m==0&&t==0)
{
break;
}
flag=0;wall=0;
memset(visit,0,sizeof(visit));
for(int i=0;i<n;i++) //画地图
{
scanf("%s",Map[i]);
}
for(int i=0;i<n;i++) //判断
{
for(int j=0;j<m;j++)
{
if(Map[i][j]=='S')
{
startx=i;starty=j;
}
if(Map[i][j]=='D')
{
endx=i;endy=j;
}
if(Map[i][j]=='X')
{
wall++;
}
}
}
if(t>n*m-wall-1) //判断时间与墙数和地图的关系
{
cout<<"NO"<<endl;
continue;
}
visit[startx][starty]=1; //标记走过的路线
dfs(startx,starty,0);
if(flag==1)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
}
return 0;
}
原题链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1010
https://vjudge.net/problem/HDU-1010