http://acm.hdu.edu.cn/showproblem.php?pid=2531
依旧广搜,要注意的是防守队员身体可能占到25格...之前没注意到这个WA了几次
code:
#include <iostream>
#include "queue"
#include "memory.h"
using namespace std;
char map[105][105]; //地图
int vit[105][105];
int n,m;
int flag; //是否能够碰到后分卫
int resulta;
int stothersum; //身体的其他占位
int fangxiang[4][2]={-1,0,1,0,0,-1,0,1};
struct point
{
int x;
int y;
};
struct shengti
{
point tou;
point otherr[35]; //其他35个身体占位
int step;
};
queue <shengti> q;
int cango(int x,int y)
{
if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y]!='O') //没超过边界且没碰到防守人
{
return 1;
}
return 0;
}
void bfs(void)
{
while(!q.empty()) //队列不为空
{
shengti temp=q.front();
q.pop();
if(flag==1) //已经找到答案
{
return;
}
int stpq=0;
int sti2;
for(sti2=0;sti2<stothersum;sti2++)
{
if(map[temp.otherr[sti2].x][temp.otherr[sti2].y]=='Q') //身体其他部位有碰到Q
{
stpq=1;
break;
}
}
if(map[temp.tou.x][temp.tou.y]=='Q'||stpq==1) //头或脚碰到后分卫则退出
{
flag=1;
resulta=temp.step;
return ;
// return temp.step; //返回步数
}
int i;
int toux=temp.tou.x; //头脚坐标都取出
int touy=temp.tou.y;
//int jiaox=temp.jiao.x;
//int jiaoy=temp.jiao.y;
for(i=0;i<4;i++) //四个方向广搜
{
int hnewx,hnewy,jnewx,jnewy;
hnewx=toux+fangxiang[i][0];
hnewy=touy+fangxiang[i][1];
int sti;
int flagst=0; //判断身体其他部位的合法性
for(sti=0;sti<stothersum;sti++)
{
jnewx=temp.otherr[sti].x+fangxiang[i][0];
jnewy=temp.otherr[sti].y+fangxiang[i][1];
if(!cango(jnewx,jnewy))
{
flagst=1;
break;
}
}
if(cango(hnewx,hnewy)&&!flagst&&vit[hnewx][hnewy]==0) //没超过连界且没碰到防守人且该新头坐标没被访问过
{
vit[hnewx][hnewy]=1;
shengti stn;
stn.tou.x=hnewx;
stn.tou.y=hnewy;
//stn.jiao.x=jnewx;
//stn.jiao.y=jnewy;
int stf;
for(stf=0;stf<stothersum;stf++) //身体其他部位赋新值
{
stn.otherr[stf].x=temp.otherr[stf].x+fangxiang[i][0];
stn.otherr[stf].y=temp.otherr[stf].y+fangxiang[i][1];
}
stn.step=temp.step+1;
q.push(stn); //新结点加入队列
}
}
}
}
int main(int argc, char *argv[])
{
while(scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
{
break;
}
while(!q.empty()) //队列清空
{
q.pop();
}
memset(vit,0,sizeof(vit)); //访问清空
int i,j;
shengti st; //防守队员身体
st.tou.x=-1;
stothersum=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
cin>>map[i][j]; //输入地图信息
if(st.tou.x==-1&&map[i][j]=='D') //输入头尾信息
{
st.tou.x=i;
st.tou.y=j;
map[i][j]=1;
}else if(map[i][j]=='D')
{
st.otherr[stothersum].x=i;
st.otherr[stothersum].y=j;
stothersum+=1; //身体的其他战位
}
}
}
st.step=0;
q.push(st);
flag=0;
bfs();
if(flag==0)
{
printf("Impossible\n");
}else
{
printf("%d\n",resulta);
}
}
return 0;
}