「BZOJ1656」[Usaco2006 Jan] The Grove 树木
Description
The pasture contains a small, contiguous grove of trees that has no ‘holes’ in the middle of the it. Bessie wonders: how far is it to walk around that grove and get back to my starting position? She’s just sure there is a way to do it by going from her start location to successive locations by walking horizontally, vertically, or diagonally and counting each move as a single step. Just looking at it, she doesn’t think you could pass ‘through’ the grove on a tricky diagonal. Your job is to calculate the minimum number of steps she must take. Happily, Bessie lives on a simple world where the pasture is represented by a grid with R rows and C columns (1 <= R <= 50, 1 <= C <= 50). Here’s a typical example where ‘.’ is pasture (which Bessie may traverse), ‘X’ is the grove of trees, ‘*’ represents Bessie’s start and end position, and ‘+’ marks one shortest path she can walk to circumnavigate the grove (i.e., the answer): …+… ..+X+.. .+XXX+. ..+XXX+ ..+X..+ …+++* The path shown is not the only possible shortest path; Bessie might have taken a diagonal step from her start position and achieved a similar length solution. Bessie is happy that she’s starting ‘outside’ the grove instead of in a sort of ‘harbor’ that could complicate finding the best path.
Input
* Line 1: Two space-separated integers: R and C
* Lines 2..R+1: Line i+1 describes row i with C characters (with no spaces between them).
Output
* Line 1: The single line contains a single integer which is the smallest number of steps required to circumnavigate the grove.
Sample Input
…….
…X…
..XXX..
…XXX.
…X…
……*
Sample Output
题解
从连通块任意一点连出去一条射线,然后计算穿过射线一次再回到起点的最小步数,同时应该限制只能从射线的一端走向另一端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #define inf 0x7fffffff #define ll long long using namespace std; int n,m,bx,by; int d[2][55][55],qx[5005],qy[5005]; int xx[8]={0,0,1,1,1,-1,-1,-1},yy[8]={1,-1,0,1,-1,0,1,-1}; bool mp[55][55],mark[55][55],flag[5005]; void bfs() { int t=0,w=1; d[0][bx][by]=0; qx[0]=bx;qy[0]=by; while(t!=w) { int x=qx[t],y=qy[t],f=flag[t];t++; for(int i=0;i<8;i++) { int nowx=x+xx[i],nowy=y+yy[i]; if(mp[nowx][nowy]||nowx<1||nowy<1||nowx>n||nowy>m)continue; if(mark[x][y]&&nowy<=y)continue; if(mark[nowx][nowy]&&nowy>y) { if(d[1][nowx][nowy]==-1) { d[1][nowx][nowy]=d[0][x][y]+1; qx[w]=nowx;qy[w]=nowy;flag[w]=1;w++; } } else { if(d[f][nowx][nowy]==-1) { d[f][nowx][nowy]=d[f][x][y]+1; qx[w]=nowx;qy[w]=nowy;flag[w]=f;w++; } } } } } int main() { memset(d,-1,sizeof(d)); scanf("%d%d",&n,&m); int tx,ty; for(int i=1;i<=n;i++) { char ch[55];scanf("%s",ch+1); for(int j=1;j<=m;j++) if(ch[j]=='X'){mp[i][j]=1;tx=i;ty=j;} else if(ch[j]=='*'){bx=i;by=j;} } for(int i=0;;i++) if(tx+i>n)break; else mark[tx+i][ty]=1; bfs(); printf("%d",d[1][bx][by]); return 0; } |