原題直通車:HDU 4528 小明系列故事——捉迷藏
分析: 標記時加兩種狀態就行.
代碼:
#include<iostream> #include<cstring> #include<queue> #include<cstdio> using namespace std; const int maxn=101; char f[maxn][maxn]; int dx[]={0,0,-1,1}; int dy[]={1,-1,0,0}; bool vis[maxn][maxn][2][2]; int n,m,k,ei,ej,di,dj,si,sj; struct node{ int x,y,time,p,q; }rt,ne; void work(node &rt){ bool u; if(!rt.p&&rt.x==ei){ int a=min(rt.y,ej), b=max(rt.y,ej); u=false; for(int i=a+1;i<b;++i) if(f[ei][i]!='.') u=true; if(!u)rt.p=1; } if(!rt.p&&rt.y==ej){ int a=min(rt.x,ei), b=max(rt.x,ei); u=false; for(int i=a+1;i<b;++i) if(f[i][ej]!='.') u=true; if(!u)rt.p=1; } if(!rt.q&&rt.x==di){ int a=min(rt.y,dj), b=max(rt.y,dj); u=false; for(int i=a+1;i<b;++i) if(f[di][i]!='.')u=true; if(!u)rt.q=1; } if(!rt.q&&rt.y==dj){ int a=min(rt.x,di), b=max(rt.x,di); u=false; for(int i=a+1;i<b;++i) if(f[i][dj]!='.') u=true; if(!u)rt.q=1; } } int BFS(){ queue<node>M; rt.x=si, rt.y=sj, rt.time=0, rt.p=0, rt.q=0; vis[si][sj][0][0]=true; M.push(rt); while(!M.empty()){ rt=M.front(); M.pop(); work(rt); if(rt.p&&rt.q) return rt.time; for(int i=0;i<4;++i){ ne=rt; ne.x+=dx[i]; ne.y+=dy[i]; ne.time+=1; if(ne.x<0||ne.x>=n||ne.y<0||ne.y>=m||ne.time>k||f[ne.x][ne.y]!='.') continue; if(!vis[ne.x][ne.y][ne.p][ne.q]){ M.push(ne); vis[ne.x][ne.y][ne.p][ne.q]=true; } } } return -1; } int main(){ int T,i,j,t,u,cas=1; scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&m,&k); for(i=0;i<n;++i){ scanf("%s",f[i]); for(j=0;j<m;++j){ if(f[i][j]=='S') si=i, sj=j,f[i][j]='.'; if(f[i][j]=='E') ei=i, ej=j; if(f[i][j]=='D') di=i, dj=j; for(t=0;t<2;++t) for(u=0;u<2;++u) vis[i][j][t][u]=false; } } printf("Case %d:\n%d\n",cas++,BFS()); } return 0; }