HDU4528 小明捉迷藏

Posted cn_XuYang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU4528 小明捉迷藏相关的知识,希望对你有一定的参考价值。

一、题意

小明S在迷宫n*m中找大明D和二明E,障碍物X不能走,问你计算是否能在时间t内找到大明和二明

二、分析

2.1与普通的BFS不同,这里可以走回头路,这里应该建立四维的标记数组标记数组,例如vis[1][0][nx][ny]表示已经找到D且没找到E且位置为(nx,ny)的状态,相同状态不可重复进入队列

2.2根据样例二可知D,E的位置不可走,起始点S的位置等价于‘.‘

2.3为了提高效率可预处理一下标记所有可以‘看到’D和E的点

三、代码 

  1 # include <iostream>
  2 # include <cstdio>
  3 # include <queue>
  4 # include <cstring>
  5 using namespace std;
  6 const int maxn=105;
  7 int cnt,T,n,m,t,vis[2][2][maxn][maxn]; 
  8 int seeE[maxn][maxn],seeD[maxn][maxn];
  9 char map[maxn][maxn];
 10 int Dx,Dy,Ex,Ey,Sx,Sy;
 11 int dx[4]={-1,1,0,0};
 12 int dy[4]={0,0,1,-1};
 13 struct Node
 14 {
 15     int tim,x,y,e,d;
 16     Node(){}
 17     Node(int ee,int dd,int tt,int xx,int yy)
 18     {
 19         e=ee;
 20         d=dd;
 21         tim=tt;
 22         x=xx;
 23         y=yy;
 24     }
 25 };
 26 void Init()
 27 {
 28     scanf("%d%d%d",&n,&m,&t);
 29     for(int i=0;i<n;i++)
 30         scanf("%s",map[i]);
 31     //for(int i=0;i<n;i++)
 32     //    printf("%s\n",map[i]); 
 33     memset(vis,0,sizeof(vis));
 34     memset(seeD,0,sizeof(seeD));
 35     memset(seeE,0,sizeof(seeE));
 36     for(int i=0;i<n;i++)
 37         for(int j=0;j<m;j++)
 38         {
 39             if(map[i][j]==S)
 40             {
 41                 Sx=i;
 42                 Sy=j;
 43             }
 44             if(map[i][j]==D)
 45             {
 46                 Dx=i;
 47                 Dy=j;
 48                 for(int i=Dx+1;i<n;i++)
 49                     if(map[i][Dy]==.||map[i][Dy]==S)
 50                         seeD[i][Dy]=1;
 51                     else break;
 52                 for(int i=Dx-1;i>=0;i--)
 53                     if(map[i][Dy]==.||map[i][Dy]==S)
 54                         seeD[i][Dy]=1;
 55                     else break;
 56                 for(int j=Dy+1;j<m;j++)
 57                     if(map[Dx][j]==.||map[Dx][j]==S)
 58                         seeD[Dx][j]=1;
 59                     else break;
 60                 for(int j=Dy-1;j>=0;j--)
 61                     if(map[Dx][j]==.||map[Dx][j]==S)
 62                         seeD[Dx][j]=1;
 63                     else break;
 64             }
 65             if(map[i][j]==E)
 66             {
 67                 Ex=i;
 68                 Ey=j;
 69                 for(int i=Ex+1;i<n;i++)
 70                     if(map[i][Ey]==.||map[i][Ey]==S)
 71                         seeE[i][Ey]=1;
 72                     else break;
 73                 for(int i=Ex-1;i>=0;i--)
 74                     if(map[i][Ey]==.||map[i][Ey]==S)
 75                         seeE[i][Ey]=1;
 76                     else break;
 77                 for(int j=Ey+1;j<m;j++)
 78                     if(map[Ex][j]==.||map[Ex][j]==S)
 79                         seeE[Ex][j]=1;
 80                     else break;
 81                 for(int j=Ey-1;j>=0;j--)
 82                     if(map[Ex][j]==.||map[Ex][j]==S)
 83                         seeE[Ex][j]=1;
 84                     else break;
 85             }
 86         }
 87 }
 88 int Solve()
 89 {
 90     int res=-1;
 91     queue<Node> Q;
 92     map[Sx][Sy]=.; 
 93     Q.push(Node(seeE[Sx][Sy],seeD[Sx][Sy],0,Sx,Sy));
 94     vis[seeE[Sx][Sy]][seeD[Sx][Sy]][Sx][Sy]=1;
 95     while(!Q.empty())
 96     {
 97         Node temp=Q.front();
 98         Q.pop();
 99         //printf("%d %d %d %d %d\n",temp.e,temp.d,temp.x,temp.y,temp.tim);
100         if(temp.tim>t) break;
101         if(temp.e+temp.d==2)
102         {
103             res=temp.tim;
104             break;
105         }
106         for(int i=0;i<4;i++)
107         {
108             int nx=temp.x+dx[i];
109             int ny=temp.y+dy[i];
110             //printf("%d %d\n",nx,ny);
111             if(nx>=0&&ny>=0&&nx<n&&ny<m&&map[nx][ny]==.)
112             {
113                 int ne=seeE[nx][ny]?1:temp.e;
114                 int nd=seeD[nx][ny]?1:temp.d;
115                 //if(nx==3&&ny==3) {printf("test:%d\n",vis[ne][nd][nx][ny]); break;}
116                 if(!vis[ne][nd][nx][ny])
117                 {    
118                     vis[ne][nd][nx][ny]=1; 
119                     Q.push(Node(ne,nd,temp.tim+1,nx,ny));
120                 }
121             }
122         }
123     }
124     return res;        
125 }
126 int main()
127 {
128     scanf("%d",&T);
129     for(int i=1;i<=T;i++)
130     {
131         Init();
132         int ans=Solve();
133         printf("Case %d:\n%d\n",i,ans);
134     }
135     return 0;
136 }

 

以上是关于HDU4528 小明捉迷藏的主要内容,如果未能解决你的问题,请参考以下文章

hdu 4528(搜索好题)

HDU 4521 小明系列问题——小明序列 (线段树维护DP)

HDU 1078 FatMouse and Cheese 简单记忆化搜索

hdu 4521 小明系列问题——小明序列(线段树+DP或扩展成经典的LIS)

HDU 2096 小明A+B(%的运用)

HDU 2096: 小明A+B