Description

 

500年前,Jesse是我国最卓越的剑客。他英俊潇洒,而且机智过人^_^。
突然有一天,Jesse心爱的公主被魔王困在了一个巨大的迷宫中。Jesse听说这个消息已经是两天以后了,他急忙赶到迷宫,开始到处寻找公主的下落。令人头痛的是,Jesse是个没什么方向感的人,因此,他在行走过程中,不能转太多弯了,否则他会晕倒的。 我们假定Jesse和公主所在的位置都是空地,初始时,Jesse所面向的方向未定,他可以选择4个方向的任何一个出发,而不算成一次转弯。希望你帮他判断一下他是否有机会找到心爱的公主。 

 

Input

 

题目包括多组测试数据.

第1行为一个整数T(1 ≤ T≤ 100),表示测试数据的个数,接下来为T组测试数据.

每组测试数据以两个整数N,M,K(1<=N, M≤100, 0<K<=10)开头,分别代表迷宫的高,长和Jesse最多能转的弯数,(紧接着有N行,M列字符,由".","*","P","S"组成。其中
"." 代表能够行走的空地。
"*" 代表墙壁,Jesse不能从此通过。
"P" 是公主所在的位置。
"S" 是Jesse的起始位置。
每个时间段里Jesse只能选择“上、下、左、右”任意一方向走一步。

 

Output

 

如果Jesse能在晕之前找到公主,输出“YES”,否则输出“NO”。

 

Sample Input

2
5 5 1
P..**
*.**.
S....
.....
*....
5 5 2
P..**
*.**.
S....
.....
*....

Sample Output

 NO

YES

http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=3305

 

 

很久之前就过了这题了,当时是用dfs过的,我也觉得会超时的了,但是提交上去10ms过了,看来还是数据太弱了。必须会超时的,网上其他代码的dfs都会超时,我试过了

40 40 10
P.*.....................................
**......................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
........................................
.......................................S

这样他们的代码就超时了,关于dfs怎么做,应该很容易想的,用dfs(x,y,face,turn)表示在[x,y]那里,面向face那里,转弯次数是turn次的情况,直接dfs即可,唯一的剪枝也就是if (turn>k),就是已经晕了就不行了吧?对于我上面那组数据都超时了,就不用想100*100的矩阵了。

dfs  AC代码(不是正解)

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (1<<28)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
int flag;
int n,m,k;
const int maxn=1e2+20;
char str[maxn][maxn];
int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
bool book[maxn][maxn];
void dfs (int x,int y,int face,int turn)
{
    if (turn>k) return ;//已经晕了就不行了
    if (str[x][y]=='P')
    {
        flag=1;//找到公主了
        return ;
    }
    for (int i=0;i<4;i++)
    {
        int tx=x+next[i][0];
        int ty=y+next[i][1];
        if (!flag&&tx>=1&&tx<=n&&ty>=1&&ty<=m&&str[tx][ty]!='*'&&book[tx][ty]==0)
        {
            book[tx][ty]=1;
            if (face!=i)
            {
                dfs(tx,ty,i,turn+1);
            }
            else dfs(tx,ty,i,turn);
            book[tx][ty]=0;
        }
    }
    return ;
}
void work ()
{
    scanf ("%d%d%d",&n,&m,&k);
    for (int i=1;i<=n;i++)
    {
        scanf ("%s",str[i]+1);
    }
    int bx,by;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            if (str[i][j]=='S')
            {
                bx=i;
                by=j;
            }
        }
    }
    flag=0;
    for (int i=0;i<4;i++)
    {
        int tx=bx+next[i][0];
        int ty=by+next[i][1];
        if (tx>=1&&tx<=n&&ty>=1&&ty<=m&&str[tx][ty]!='*')
        {
            memset (book,0,sizeof(book));
            if (str[tx][ty]=='P')
            {
                printf ("YES\n");
                return ;
            }
            dfs(tx,ty,i,0);
            if (flag)
            {
                printf ("YES\n");
                return ;
            }
        }
    }
    printf ("NO\n");
    return ;
}
int main ()
{
    #ifdef local
    freopen("data.txt","r",stdin);
    #endif
    int t;
    scanf ("%d",&t);
    while (t--)
    {
        work ();
    }
    return 0;
}
View Code

相关文章: