1. 程式人生 > >HDU4528 小明捉迷藏

HDU4528 小明捉迷藏

分析 queue %d stream printf const for 高效率 using

一、題意

小明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 小明捉迷藏