题目请戳这里
题目大意:给一个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