Tempter of the Bone

小明做了一个很久很久的梦,醒来后他竟发现自己和朋友在一个摇摇欲坠的大棋盘上,他们必须得想尽一切办法逃离这里。
经过长时间的打探,小明发现,自己所在的棋盘格子上有个机关,上面写着“你只有一次机会,出发后t秒大门会为你敞开”,而他自己所在的棋盘是大小为 N*M 的长方形,他可以向上下左右四个方向移动(不可走有障碍点)。棋盘中有一扇门。根据机关的提示,小明顿时明白了,他和朋友必须在第 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
注意:
这题有许多坑,至少我wa了好多次;
1.棋盘输入必须有%s(用%c wa了);
2.必须奇偶剪枝,否则后超时;
3.必须统计障碍点数,有n*m-jw-1>=lim;(其中n是纵数,m是行数,jw是障碍点数,lim是门打开的时间数)可以快速在障碍点过多的情况下,避免深搜,得出结果;

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
char arr[10][10];
int open[10][10];
int  n,m,lim,flag=0,ex=0,ey=0;
int np[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
void DFS(int x,int y ,int step){
     if(x==ex&&y==ey&&step==lim){
            flag=1;
          return ;
     }
     //在已可逃离情况下,将所有深搜停止,减少运行时间;
     if(step>=lim||flag==1)
        return ;
    //奇偶剪枝
    int s=(lim-step)-abs(x-ex)-abs(y-ey);
    if(s<0||s%2==1)
        return ;
     for(int i=0;i<4;i++){
            int nx=x+np[i][0];
            int ny=y+np[i][1];
            if(nx<0||ny<0||nx>=n||ny>=m||open[nx][ny]==1||arr[nx][ny]=='X')
                continue;
            open[nx][ny]=1;
            DFS(nx,ny,step+1);
            open[nx][ny]=0;
        }
}
int main()
{
    int bx=0,by=0,jw=0;
    while(scanf("%d %d %d",&n,&m,&lim)!=EOF&&n!=0&&m!=0&&lim!=0){
        memset(open,0,sizeof(open));
        flag=0,jw=0;
     for(int i=0;i<n;i++)
        scanf("%s",arr[i]);
     for(int i=0;i<n;i++){
          for(int t=0;t<m;t++){
            if(arr[i][t]=='S')
                bx=i,by=t;
          else if(arr[i][t]=='D')
                ex=i,ey=t;
          else if(arr[i][t]=='X')
                    jw++;
          }
     }
        int s=abs(ex-bx)+abs(ey-by);
        if(s<=lim&&(lim-s)%2==0&&n*m-jw-1>=lim){//奇偶剪枝加障碍排除(!!!)
              open[bx][by]=1;
             DFS(bx,by,0);
        }
        if(flag==0)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值