hdu-1010 Tempter of the Bone

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1010

题目:

Tempter of the Bone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 119983    Accepted Submission(s): 32412


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

题意概述:

 有一个狗发现了一个古老的迷宫,然后这个古老的迷宫中有一个骨头,问这只狗能否用时间t从坐标为(stx,sty)恰好(必须在时间为t的时候到达,不能提前)到坐标为(edx,edy)的骨头哪里。

解题思路:

这道题用广搜妥妥的,但是用深搜如果不剪枝一定会超时(不要问我为什么知道,虽然最大为7*7的迷宫)但是因为广搜的代码长度、、、算了,我还是深搜吧,然后根据大神的解题报告我了解了奇偶剪枝,也就是如果当前坐标和加上到达目的地的时间(stx+sty+t)如果与目的地的坐标和(edx+edy)奇偶性不同,则证明小狗一定不能准时到达骨头那里。例如第二个样例

X/Y 1 2 3 4
1 0 1 0 1
2 1 0 1 0
3 0 1 0 1

根据下标和对2取余发现小狗的坐标S(1,1)对2取余为0,骨头的坐标D(3,4)对2取余为1,然后(0+5)%2=1;1==1;所以,根据奇偶性。小狗是可以到达重点的。然后根据奇偶剪枝后的dfs直接AC,毫不拖泥带水~

AC代码:

# include <stdio.h>
# include <string.h>

int n,m,t,flag,ret;
char map[10][10];

void dfs(int x,int y,int l)
{
    if(flag==1)
        return ;
    if(l==t && map[x][y]=='D')
        flag=1;
    
    if(l!=t && map[x][y]=='D')
        return ;
    
    if( (x+y+t-l)%2!=ret)
        return ;
    
    if(y<n && map[x][y+1]!='X')//r
    {
        map[x][y]='X';
        dfs(x,y+1,l+1);
        map[x][y]='.';
    }
    
    if(y>1 && map[x][y-1]!='X')//l
    {
        map[x][y]='X';
        dfs(x,y-1,l+1);
        map[x][y]='.';
    }
    
    if(x<n && map[x+1][y]!='X')//d
    {
        map[x][y]='X';
        dfs(x+1,y,l+1);
        map[x][y]='.';
    }
    
    if(x>1 && map[x-1][y]!='X')//u
    {
        map[x][y]='X';
        dfs(x-1,y,l+1);
        map[x][y]='.';
    }
        
}

int main ()
{
    int i,j;
    int stx,sty,edx,edy;
    while(scanf("%d%d%d",&m,&n,&t)!=EOF)
    {
        if(m==0 && n==0 && t==0)
            break;
        getchar();
        for(i=1;i<=m;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%c",&map[i][j]);
                if(map[i][j]=='S')
                {
                    stx=i; sty=j;
                }
                if(map[i][j]=='D')
                {
                    edx=i; edy=j;
                }
            }    
            getchar();    
        }
        flag=0;
        ret=(edx+edy)%2;
        dfs(stx,sty,0);
        if(flag==1)
            printf("YES
");
        else
            printf("NO
");
    }
}
原文地址:https://www.cnblogs.com/love-sherry/p/6745291.html