题目大意:给一个n*m的地图,由'X'和空格组成,'X'表示物体,'.'表示空地。再给若干组数据,每组数据为2个坐标,问这2个坐标点之间能否连同,如果能,需要多少线段使之联通。可以借助地图外面的空间。
题目分析:其实就是求给定的坐标对之间所有路径最少拐弯次数。记忆化搜索解决。给定的两点中任选1个点做起点,开始搜索,记录下其余每个点最少需要拐弯多少次到达。
最后直接判断目标点状态就可以了。
详情请见代码:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N = 80;
const int M = 100004;
int n,m,sx,sy,ex,ey;
int dir[4][2] = {{-1,0},{0,-1},{0,1},{1,0}};
char mp[N][N];
int flag[N][N];
bool isok(int x,int y)
{
return (x >= 0 && y >= 0 && x <= n + 1 && y <= m + 1);
}
void dfs(int cx,int cy,int di,int dp)
{
int i;
for(i = 0;i < 4;i ++)
{
int tx = cx + dir[i][0];
int ty = cy + dir[i][1];
while(isok(tx,ty))
{
if(mp[tx][ty] == 'X')
{
if(tx == ex && ty == ey)
flag[tx][ty] = min(flag[tx][ty],dp);
break;
}
else
{
if(di == i)
{
if(flag[tx][ty] > dp)
{
flag[tx][ty] = dp;
dfs(tx,ty,di,dp);
}
}
else
{
if(flag[tx][ty] > dp + 1)
{
flag[tx][ty] = dp + 1;dfs(tx,ty,i,dp + 1);
}
}
}
tx += dir[i][0];
ty += dir[i][1];
}
}
}
void fuck()
{
int i,j,cas;
cas = 0;
memset(mp,0,sizeof(mp));
for(i = 1;i <= n;i ++)
{
for(j = 1;j <= m;j ++)
mp[i][j] = getchar();
getchar();
}
while(scanf("%d%d%d%d",&sy,&sx,&ey,&ex),(sx + sy + ex + ey))
{
printf("Pair %d: ",++cas);
memset(flag,0x3f,sizeof(flag));
flag[sx][sy] = 0;
dfs(sx,sy,-1,1);
if(flag[ex][ey] == 0x3f3f3f3f)
puts("impossible.");
else
printf("%d segments.\n",flag[ex][ey]);
}
puts("");
}
int main()
{
int cas = 0;
while(scanf("%d%d",&m,&n),(n + m))
{
getchar();
printf("Board #%d:\n",++ cas);
fuck();
}
return 0;
}
//972K 0MS