这题坑了我好久,还是那句话只要你真心去做一定能想出办法来。这题办法倒是想出来了,但是我标记的是身体的全部,每次都这样,只有检测到全部被标记时才不继续往下搜索,测试数据试很多也没找出错误来,最后才知道只要标记一个就行,而且必须一直标记同一个。。
代码:
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std ;
int r ;
int n,m ;
int vx[105],vy[105] ;
char s[105][105] ;
int vis[105][105] ;
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1} ;
struct zhang
{
int x[25],y[25],bu ;
} ;
int bfs()
{
queue<zhang>q ;
zhang current,next ;
int i,j,k ;
int nx,ny ;
for(i=0;i<r;i++)
{
current.x[i]=vx[i] ;
current.y[i]=vy[i] ;
}
vis[current.x[0]][current.y[0]]=1 ;//每次标记开始那一点
current.bu=0 ;
q.push(current) ;
while(!q.empty())
{
current=q.front() ;
q.pop() ;
for(i=0;i<4;i++)
{
int p=0,ret=0 ;
for(j=0;j<r;j++)
{
next.x[j]=current.x[j]+dx[i] ;
next.y[j]=current.y[j]+dy[i] ;
nx=next.x[j] ;
ny=next.y[j] ;
if(!j&&vis[nx][ny])
ret=1 ;
if(nx<0||nx>=n||ny<0||ny>=m||s[nx][ny]=='O')
{
ret=1 ;
break ;
}
if(s[nx][ny]=='Q')
p=1 ;
}
if(ret)
continue ;
if(p)
return current.bu+1 ;
for(k=0;k<r;k++)
{
next.x[k]=current.x[k]+dx[i] ;
next.y[k]=current.y[k]+dy[i] ;
nx=next.x[k] ;
ny=next.y[k] ;
if(!k)
vis[nx][ny]=1 ;
}
next.bu=current.bu+1 ;
q.push(next) ;
}
}
return -1 ;
}
int main()
{
int i,j ;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n&&!m)
break ;
r=0 ;
memset(vis,0,sizeof(vis)) ;
for(i=0;i<n;i++)
{
scanf("%s",s[i]) ;
for(j=0;j<m;j++)
if(s[i][j]=='D')
{
vx[r]=i ;
vy[r]=j ;
r++ ;
}
}
int mx=bfs() ;
if(mx==-1)
printf("Impossible\n") ;
else printf("%d\n",mx) ;
}
return 0 ;
}