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
6 7 ....... ...X... ..XXX.. ...XXX. ...X... ......*
Sample Output
13
题意:‘*’为起点,X为森林,Bessie要绕森林一周回到起点
思路:求最短路首先想到BFS,接着怎么才能绕森林一圈还不会直接回到起点呢!先预处理x,已某一个x为一个射线,超过以X为射线 的时候不能往回搜,当搜到在该射线上时,就标记可以回到起点,否则不能回到起点,这样不仅可以绕森林一圈,而且还可以不会一开始就 回到起点!
#include <iostream> #include <queue> #include <algorithm> #include <string.h> using namespace std; struct node { int x,y,step; int f; }; int n,m,sx,sy; int Map[55][55],flag[55][55][2]; int dir[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1}; int bfs( ) { queue<node>q; node now,next; now.x = sx; now.y = sy; now.f = 0; now.step = 0; flag[sx][sy][0] = 1; q.push(now); while(!q.empty()) { now = q.front(); q.pop(); if(now.x == sx && now.y == sy && flag[now.x][now.y][1]) return now.step; for(int i=0;i<8;i++) { int xx = now.x + dir[i][0]; int yy = now.y + dir[i][1]; // if(xx < 1 || xx >n || yy < 1 || yy > m) // continue; if(!Map[xx][yy]) continue; if((Map[xx][yy] == 2 || Map[now.x][now.y] == 2) && yy<now.y)//当前在射线上或下一个点在射线上,从右到左,不能像左走 continue; // cout<<"xx="<<xx<<" "<<"yy="<<yy<<endl; if(Map[now.x][now.y] == 2)//找到该射线,更新点! { if(!flag[xx][yy][1]) { flag[xx][yy][1] = 1; next.x = xx; next.y = yy; next.f = 1; next.step = now.step + 1; q.push(next); } } else { if(!flag[xx][yy][now.f]) { flag[xx][yy][now.f] = 1; next.x = xx; next.y = yy; next.step = now.step + 1; next.f = now.f; q.push(next); } } // q.push(next); } } return -1; } int main() { cin>>n>>m; char ch; memset(flag,0,sizeof(flag)); memset(Map,0,sizeof(Map)); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>ch; if(ch == 'X') Map[i][j] = 0; else { Map[i][j] = 1; if(ch == '*') { sx= i; sy = j; } } } } int b,c = -1; for(int i=1;i<=n&&c<0;i++) { for(int j=1;j<=m&&c<0;j++) { if(!Map[i][j]) { b=i; c=j; } } } for(int i=1;i<b;i++) { Map[i][c] = 2; } // for(int i=1;i<=n;i++) // { // for(int j=1;j<=m;j++) // cout<<Map[i][j]<<" "; // cout<<endl; // } cout<<bfs()<<endl; return 0; }