Tempter of the Bone

Problem Description

The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.

The maze was a rectangle with sizes N by M. There was a door in the maze. At the beginning, the door was closed and it would open at the T-th second for a short period of time (less than 1 second). Therefore the doggie had to arrive at the door on exactly the T-th second. In every second, he could move one block to one of the upper, lower, left and right neighboring blocks. Once he entered a block, the ground of this block would start to sink and disappear in the next second. He could not stay at one block for more than one second, nor could he move into a visited block. Can the poor doggie survive? Please help him.

Input

The input consists of multiple test cases. The first line of each test case contains three integers N, M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes of the maze and the time at which the door will open, respectively. The next N lines give the maze layout, with each line containing M characters. A character is one of the following:

'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.

The input is terminated with three 0's. This test case is not to be processed.

Output

For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.

Sample Input

4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0

Sample Output

NO
YES
题意:给定一个二维图(m*n),图中有些点可走有些不可走,给出起点和终点,判断是否在t时刻能够刚好到达终点位置
题解:因为是刚好到达,故是明显的深搜。该题需要有剪枝否则会超时
剪枝一:对初始状态判断,看起点终点的距离是否小于等于给定的时间,图中可走的点的个数
剪枝二:奇偶剪枝(末位置与当前位置之差与总时间与当前时间之差奇偶性必须相同。即所谓的距离时间满足奇偶性相同
剪枝三:搜索到时间如果超过给定的时间应该跳出。如果剩下的距离大于剩下的时间也应该跳出
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
bool p[10][10];
char mr[10][10];
int m,n,t;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int sx,sy,tx,ty;
int flag;
int abs(int a)
{
 if(a<0) return -a;
 else return a;
}
void dfs(int x,int y,int tr)
{
    int xx,yy,i;
 if(tr==t&&x==tx&&y==ty)
    {
        flag=1;
    }
    if(flag) return;
    if(tr>t||abs(t-tr)%2!=(abs(tx-x)+abs(ty-y))%2||(t-tr)<abs(tx-x)+abs(ty-y)) return;
    for(i=0;i<4;i++)
    {
        xx=x+dir[i][0];
        yy=y+dir[i][1];
        if(!p[xx][yy]&&xx>=0&&xx<m&&yy>=0&&yy<n)
        {
            p[xx][yy]=true;
            dfs(xx,yy,tr+1);
            p[xx][yy]=false;
        }
    }
}
int main()
{
    int i,j,cnt;
    while(scanf("%d%d%d",&m,&n,&t))
    {
        if(m==0&&n==0&&t==0) break;
        getchar();
  memset(p,false,sizeof(p));
  cnt=0;
        for(i=0;i<m;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%c",&mr[i][j]);
                if(mr[i][j]=='X')  {p[i][j]=1;}
                if(mr[i][j]=='S')  {sx=i;sy=j;}
                if(mr[i][j]=='D')  {tx=i;ty=j;}
    else cnt++;
            }
            getchar();
        }
        if(cnt<t-1||t<abs(tx-sx)+abs(ty-sy)) puts("NO");
        else
        {
            flag=0;
            p[sx][sy]=true;
            dfs(sx,sy,0);
            if(flag) puts("YES");
            else puts("NO");
        }
    }
    return 0;
}
 
posted @ 2013-08-12 11:11  forevermemory  阅读(167)  评论(0编辑  收藏  举报