HDU 2102 A计划

来源:互联网 发布:淘宝职业女装红色裙子 编辑:程序博客网 时间:2024/06/04 19:33

题意:两层迷宫,迷宫的入口是S(0,0,0),出口是P,时空传输机用'#'表示,墙用'*'表示,平地用'.'表示,进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死,骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。n x m的迷宫,骑士能否在t时刻内走出迷宫

解题思路:深搜dfs.这道题是问能否在t时刻内走出迷宫,可以用bfs找出最短路径花费的时间,如果比t小就可以走出。这里我是用dfs实现的,可以走出就直接退出。首先要判断如果第一层是‘#’,第二层的对应位置也是‘#’,那么是无法走出的,可以直接把这两个位置变成墙,如果第一层是‘#’,第二层的对应位置是‘*’,那么骑士就会被撞死,也是无法走出的,可以把第一层的‘#’变成墙,同理如果第一层是‘*’,第二层的对应位置是‘#’,就把第二层的对应位置的‘#’变成墙。接下来按照套路深搜就可以了,为了防止内存超限,就要通过剪枝减少递归层数,如果不满足条件直接回退,如果找到一个满足条件的就直接退出,不再往下进行了。

注意:如果写成int dr[]={0,0,1,-1};int dc[]={1,-1,0,0}是会超时的,据说是因为这个走法可能走的步数比较多。以后一定要写成int dr[]={-1,0,1,0};int dc[]={0,1,0,-1};因为这个地方被卡了一天超时...

代码

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cmath>#include <cstdio>using namespace std;char g[2][15][15];int vis[2][15][15];int n,m,t;int dr[]={-1,0,1,0};int dc[]={0,1,0,-1};inline bool inside(int x,int y){    return x>=0&&x<n&&y>=0&&y<m;}int dfs(int l,int x,int y,int step){    if(step>t)return 0;    if(g[l][x][y]=='P')return 1;    for(int i=0;i<4;i++)    {        int nx=x+dr[i],ny=y+dc[i];        if(inside(nx,ny)&&!vis[l][nx][ny]&&g[l][nx][ny]!='*')        {            if(g[l][nx][ny]=='#')            {                vis[l][nx][ny]=1;                vis[(l+1)%2][nx][ny]=1;                if(dfs((l+1)%2,nx,ny,step+1))return 1;                vis[(l+1)%2][nx][ny]=0;                vis[l][nx][ny]=0;            }            else            {                vis[l][nx][ny]=1;                if(dfs(l,nx,ny,step+1))return 1;                vis[l][nx][ny]=0;            }        }    }    return 0;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&n,&m,&t);        for(int i=0;i<n;i++)        {            scanf("%s",g[0][i]);        }        for(int i=0;i<n;i++)        {            scanf("%s",g[1][i]);        }        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                if(g[0][i][j]=='#'&&g[1][i][j]=='#')g[0][i][j]='*',g[1][i][j]='*';                else if(g[0][i][j]=='#'&&g[1][i][j]=='*')g[0][i][j]='*';                else if(g[0][i][j]=='*'&&g[1][i][j]=='#')g[1][i][j]='*';            }        }        memset(vis,0,sizeof(vis));        vis[0][0][0]=1;        int flag=dfs(0,0,0,0);        if(flag)printf("YES\n");        else printf("NO\n");    }    return 0;}