题目大意:中文题,很简单,自己看。
题目分析:本题也是迷宫搜索类的,不过和一般的迷宫问题不一样的是本题的搜索者有着庞大的身躯,所以一步要占几个格子。不过这对我们的搜索策略并无多大影响,我们只需在移动的时候将搜索者身体所占的地方同时向一个方向移动就可以了。本题要求最少步数,故用bfs。搜索者的身体不超过20格,用结构体保存搜索者的身体信息,从起点开始搜。搜索前先想好判重问题,由于本题给的是100*100的地图,所以我给每个格子编号,第i行j列的格子编号i*m+j,m是地图的列,然后每个节点加一个val值,代表当前搜索者所占位置的编号和,仔细想想,搜索者身体是不变的,因此不同位置会有不同的val值,可以估计最大的val值不会超过20万。详情请见代码:
#include <iostream>
#include<cstdio>
#include<queue>
using namespace std;
const int N = 105;
char map[N][N];
bool flag[200000];
int n,m;
int dire[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};//右,左,上,下
struct node
{
int i[21],j[21];
int num,val,step;
}s,now;
queue<struct node>myque;
int ok;
int isok(int id)
{
int mark = 0;
int i;
s.val = 0;
for(i = 0;i < s.num;i ++)
{
s.i[i] += dire[id][0];
s.j[i] += dire[id][1];
s.val += (s.i[i] * m + s.j[i]);
if(s.i[i] < 0 || s.i[i] >= n || s.j[i] < 0 || s.j[i] >= m)
return 0;
if(map[s.i[i]][s.j[i]] == 'O')
return 0;
if(map[s.i[i]][s.j[i]] == 'Q')
mark = 1;
}
if(mark)
ok = 1;
return 1;
}
void bfs()
{
while(!myque.empty())
myque.pop();
int i;
//printf("%d\n",s.val);
myque.push(s);
flag[s.val] = 1;
while(!myque.empty())
{
now = myque.front();
myque.pop();
for(i = 0;i < 4;i ++)
{
s = now;
if(isok(i) && !flag[s.val])
{
flag[s.val] = 1;
s.step = now.step + 1;
if(ok)
{
printf("%d\n",s.step);
return ;
}
//printf("%d\n",s.val);
myque.push(s);
}
}
}
printf("Impossible\n");
}
int main()
{
int i,j;
while(scanf("%d%d",&n,&m),(m + n))
{
getchar();
s.val = s.num = s.step = 0;
for(i = 0;i < n;i ++)
{
for(j = 0;j < m;j ++)
{
map[i][j] = getchar();
if(map[i][j] == 'D')
{
s.i[s.num] = i;
s.j[s.num] = j;
s.num ++;
s.val += (i * m + j);
}
}
getchar();
}
memset(flag,0,sizeof(flag));
ok = 0;
bfs();
}
return 0;
}
//15MS 580K
/*
5 6
...Q..
.O.O..
......
..OO.O
....DD
*/