题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2531
以整块里面的最左上角的点作为代表,将所有边界上的点和代表点的相对距离存储在结构体里面,就转变成一个点的BFS了,然后改写一下check函数。
让我想到了像素游戏里面人物的移动,不知道是不是就是这样设计的。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#define FOR(i,k,n) for(int i=k;i<n;i++)
#define FORR(i,k,n) for(int i=k;i<=n;i++)
#define scan(a) scanf("%d",&a)
#define scann(a,b) scanf("%d%d",&a,&b)
#define scannn(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define mst(a,n) memset(a,n,sizeof(a));
#define ll long long
#define N 105
#define mod 1000000007
#define INF 0x3f3f3f3f
int n,m;
char map[N][N];
int vis[N][N];
int uIndex,dIndex,lIndex,rIndex;
int go[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int flag;
typedef struct Point
{
int x,y;
int step;
//Point(int xx,int yy):x(xx),y(yy){}
}point;
struct node
{
point border[20];
int index;
}D[4];
bool check(int x,int y,int dir)
{
int j=0;
for(;j<D[dir].index;j++)
{
int xx=x+D[dir].border[j].x;
int yy=y+D[dir].border[j].y;
if(!(xx>=0&&xx<n&&yy>=0&&yy<m&&map[xx][yy]!='O'))
break;
else
{
if(map[xx][yy]=='Q')
flag=1;
}
}
if(j<D[dir].index)
{
flag=0;
return false;
}
else
return true;
}
int Bfs(int sx,int sy)
{
point s; s.x=sx; s.y=sy; s.step=0;
queue<point> q;
q.push(s);
while(!q.empty())
{
point cur=q.front();
q.pop();
//根结点全是D,不包含Q,即若有解的话,ans>=1,所以根结点不用check,故check函数可以移到for循环里面,
//检测所有产生的子节点即可
for(int i=0;i<4;i++)
{
int x=cur.x+go[i][0];
int y=cur.y+go[i][1];
if(!vis[x][y]&&check(x,y,i))
{
vis[x][y]=1;
point tmp;
tmp.x=x; tmp.y=y;
tmp.step=cur.step+1;
if(flag)
return tmp.step;
q.push(tmp);
}
}
}
return -1;
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(~scann(n,m)&&!(!n&&!m))
{
mst(vis,0);
mst(map,'.');//之前没加这句,导致判断D的边界的时候,因上一组数据残留的字符'D'
//而造成了与map边界重合的D的边界的部分丢失
flag=0;
uIndex=0,dIndex=0,lIndex=0,rIndex=0;
int first=0,sx=-1,sy=-1;
FOR(i,0,n)
{
getchar();
FOR(j,0,m)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='D')
{
if(!first){
first=1;
sx=i; sy=j;
}
if(map[i][j+1]!='D')
{
D[0].border[rIndex].x=i-sx;
D[0].border[rIndex].y=j-sy;
rIndex++;
}
if(map[i+1][j]!='D')
{
D[1].border[dIndex].x=i-sx;
D[1].border[dIndex].y=j-sy;
dIndex++;
}
if(map[i][j-1]!='D')
{
D[2].border[lIndex].x=i-sx;
D[2].border[lIndex].y=j-sy;
lIndex++;
}
if(map[i-1][j]!='D')
{
D[3].border[uIndex].x=i-sx;
D[3].border[uIndex].y=j-sy;
uIndex++;
}
}
}
}
D[0].index=rIndex; D[1].index=dIndex; D[2].index=lIndex; D[3].index=uIndex;
vis[sx][sy]=1;
int ans=Bfs(sx,sy);
if(ans!=-1)
printf("%d\n",ans);
else
printf("Impossible\n");
}
return 0;
}