Blade and Sword
1) '.' represents an empty space. The player can move through it.
2) '#' represents wall, and the player cannot move through it. You can assume that the boundaries
of the grid will be walls.
3) '*' means a teleporting cell, once the player moves into this cell, he must choose any other
teleporting cell where he will be taken to. But if he cannot find a desired teleporting cell, he
will die. However, after moving to the desired teleporting cell, he can either move to an
adjacent cell, or he can teleport again using the same procedure.
4) 'P' means the position of the player and there will be exactly one cell containing 'P'.
5) 'D' means the destination cell and there will be exactly one cell containing 'D'.
Now you are given a stage and the player starts moving. It takes one unit of time for the player to
move to any adjacent cell from his current position. Two cells are adjacent if they share a side. One
unit of time is needed for the teleporting service; that means taking the player from one teleporting cell
to any other teleporting cell. Your task is to find the minimum possible time unit required for the
player to reach the destination cell.
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <string>
#include <time.h>
#include <math.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
#define inf 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
typedef long long ll;
const int maxn=300;
int n,m,t;
char mp[maxn][maxn];
bool vis[maxn][maxn];
bool must_go[maxn][maxn];
struct node{
int x,y,step;
}sta,end,u,v;
queue<node>q;
vector<node>p;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
bool flag=0;
int main()
{
cin>>t;
for(int T=1;T<=t;T++)
{
memset(vis,0,sizeof(vis));
memset(mp,0,sizeof(mp));
memset(must_go,0,sizeof(must_go));
p.clear();
while(!q.empty())q.pop();
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",mp[i]);
for(int j=0;j<m;j++)
{
if(mp[i][j]=='P')
{
sta.x=i;
sta.y=j;
sta.step=0;
vis[i][j]=1;
q.push(sta);
}
if(mp[i][j]=='*')
{
sta.x=i;
sta.y=j;
p.push_back(sta);
}
}
}
int ans=inf;
flag=0;
while(!q.empty())
{
if(flag==1)break;
u=q.front();
q.pop();
if(mp[u.x][u.y]=='*')
{
for(int i=0;i<p.size();i++)
{
if(vis[p[i].x][p[i].y]==0&&(!(p[i].x==u.x&&p[i].y==u.y)))
{
vis[p[i].x][p[i].y]=1;
p[i].step=u.step+1;
q.push(p[i]);
}
}
p.clear();
if(!vis[u.x][u.y])p.push_back(u);
if(must_go[u.x][u.y]==1)
{
must_go[u.x][u.y]=0;
continue;
}
}
for(int i=0;i<4;i++)
{
v.x=u.x+dx[i];
v.y=u.y+dy[i];
v.step=u.step+1;
if(mp[v.x][v.y]=='#')continue;
if(!vis[v.x][v.y])
{
if(mp[v.x][v.y]=='D')
{
ans=v.step;
flag=1;
break;
}else
if(mp[v.x][v.y]=='*')
{
must_go[v.x][v.y]=1;
q.push(v);
}else
if(mp[v.x][v.y]=='.'&&vis[v.x][v.y]==0)
{
vis[v.x][v.y]=1;
q.push(v);
}
}
}
}
printf("Case %d: ",T);
if(ans==inf)
{
printf("impossible\n");
}else printf("%d\n",ans);
}
return 0;
}