The Grove
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 641   Accepted: 297

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

6 7
.......
...X...
..XXX..
...XXX.
...X...
......*

Sample Output

13

Source

思路:

突破口肯定是必须要围绕果园走一圈了,那么起点到一个点分顺时针和逆时针经过果园用bfs求两次最短路就够了,比赛时想了很久都没想到处理顺时针和逆时针的方法,就只能想到这步了,思维还是不能突破呀。

怎样处理顺时针和逆时针呢?从果园中引一条射线出去与地图边界相交,从起点出发两次bfs,一次控制只能向上经过射线,一次控制只能向下进过射线就够了。因为绕果园必须要经过射线上一点,所以最后用射线上的点来更新答案就OK了。

注意:

那个射线不能随便作的,要保证射线不与果园再次相交。想一想,为什么?

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
//#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 105
#define mod 1000000007
#define INF 0x3f3f3f3f
using namespace std; typedef long long ll;
int n,m,ans;
int sx,sy;
int dx[]={-1,1,0,0,-1,-1,1,1};
int dy[]={0,0,-1,1,-1,1,-1,1};
int dist[maxn][maxn][2];
bool vis[maxn][maxn][2];
char mp[maxn][maxn];
char s[maxn];
struct Node
{
int x,y;
}cur,now;
queue<Node>q; void presolve()
{
int i,j,k,flag=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(mp[i][j]=='X')
{
flag=1;
for(k=j-1;k>=1;k--) // 将射线标记
{
if(mp[i][k]=='X') continue ;
mp[i][k]='Y';
}
break ;
}
}
if(flag) break ;
}
}
void bfs(int k)
{
int i,j,nx,ny,tx,ty;
while(!q.empty()) q.pop();
cur.x=sx;
cur.y=sy;
dist[sx][sy][k]=0;
vis[sx][sy][k]=1;
q.push(cur);
while(!q.empty())
{
now=q.front();
q.pop();
nx=now.x;
ny=now.y;
for(i=0;i<8;i++)
{
tx=nx+dx[i];
ty=ny+dy[i];
if(tx<1||tx>n||ty<1||ty>m||mp[tx][ty]=='X'||vis[tx][ty][k]) continue ;
if(k&&mp[tx][ty]=='Y') // 到Y时控制过去的方向就好了
{
if(i==1||i==6||i==7) continue ;
}
else if(!k&&mp[tx][ty]=='Y') // 到Y时控制过去的方向就好了
{
if(i==0||i==4||i==5) continue ;
}
cur.x=tx;
cur.y=ty;
dist[tx][ty][k]=dist[nx][ny][k]+1;
vis[tx][ty][k]=1;
q.push(cur);
}
}
}
void solve()
{
int i,j;
ans=INF;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(mp[i][j]=='Y')
{
ans=min(ans,dist[i][j][0]+dist[i][j][1]);
}
}
}
}
int main()
{
int i,j,t;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
{
scanf("%s",s);
for(j=1;j<=m;j++)
{
mp[i][j]=s[j-1];
if(mp[i][j]=='*') sx=i,sy=j;
}
}
presolve();
memset(vis,0,sizeof(vis));
bfs(0);
bfs(1);
solve();
printf("%d\n",ans);
}
return 0;
}

poj 3182 The Grove的更多相关文章

  1. poj 3182 The Grove bfs

    思路:如果要围绕一圈,必须经过一条竖线上的一点,把竖线左端封住,bfs一次,枚举点,再把竖线右端封住,再bfs回起点. #include <iostream> #include <c ...

  2. POJ 3182 The Grove [DP(spfa) 射线法]

    题意: 给一个地图,给定起点和一块连续图形,走一圈围住这个图形求最小步数 本来是要做课件上一道$CF$题,先做一个简化版 只要保证图形有一个点在走出的多边形内就可以了 $hzc:$动态化静态的思想,假 ...

  3. The Grove(poj 3182)

    题意:一个n*m(n,m<=50)的矩阵有一片连着的树林,Bessie要从起始位置出发绕林子一圈再回来,每次只能向横着.竖着或斜着走一步.问最少需多少步才能完成. /* 如果我们用搜索来写的话, ...

  4. [USACO2006][poj3182]The Grove(巧妙的BFS)

    题目:http://poj.org/problem?id=3182 题意:一个棋盘中间有一个联通块,给你一个起点让你从起点开始绕联通块外围一圈并回到起点,求最小步数. 分析: 首先根据数据的范围比较小 ...

  5. POJ 2387 Til the Cows Come Home

    题目链接:http://poj.org/problem?id=2387 Til the Cows Come Home Time Limit: 1000MS   Memory Limit: 65536K ...

  6. Poj 3982 序列

    1.Link: http://poj.org/problem?id=3982 2.Content: 序列 Time Limit: 1000MS   Memory Limit: 65536K Total ...

  7. POJ 2387 Til the Cows Come Home(模板——Dijkstra算法)

    题目连接: http://poj.org/problem?id=2387 Description Bessie is out in the field and wants to get back to ...

  8. 链式前向星版DIjistra POJ 2387

    链式前向星 在做图论题的时候,偶然碰到了一个数据量很大的题目,用vector的邻接表直接超时,上网查了一下发现这道题数据很大,vector可定会超的,不会指针链表的我找到了链式前向星这个好东西,接下来 ...

  9. POJ 2387 Til the Cows Come Home (图论,最短路径)

    POJ 2387 Til the Cows Come Home (图论,最短路径) Description Bessie is out in the field and wants to get ba ...

随机推荐

  1. oracle中使用minus进行数据排除(类似SqlServer except函数)

    minus这个集合操作符号的作用是从一个结果集合中减掉另一个结果集中数据,也就是说从一个结果集中去除两个结果集中的共有部分. 下面是一些例子: 这个例子使用minus从第一个结果集中将两个结果集的公有 ...

  2. Swift - 32 - 函数类型

    //: Playground - noun: a place where people can play import UIKit func add(a:Int, b:Int) -> Int { ...

  3. JS格式化数字金额用逗号隔开保留两位小数

    JS格式化金额,正则方式修改. /** * 格式化金额 * @param {[type]} v [要转换的数字] * @param {[type]} len [小数点位数,默认2位] * @param ...

  4. java_reflect_03

    关于反射在annotation中的使用,这也是本次我个人学习反射的主要目的 关于什么是annotation后续我也会整理一下,现在只大致介绍一下 一,Annotation(注解)简介: 注解大家印象最 ...

  5. Hive学习之六 《Hive进阶— —hive jdbc》 详解

    接Hive学习五 http://www.cnblogs.com/invban/p/5331159.html 一.配置环境变量 hive jdbc的开发,在开发环境中,配置Java环境变量 修改/etc ...

  6. Hadoop 中 IPC 的源码分析

    最近开始看 Hadoop 的一些源码,展开hadoop的源码包,各个组件分得比较清楚,于是开始看一下 IPC 的一些源码. IPC模块,也就是进程间通信模块,如果是在不同的机器上,那就可以理解为 RP ...

  7. C++ Primer 5th 第16章 模板与泛型编程

    模板是C++中泛型编程的基础,一个模板就是创建一个类或者函数的蓝图或者说公式. C++模板分为函数模板和类模板. 类模板则可以是整个类是个模板,类的某个成员函数是个模板,以及类本身和成员函数分别是不同 ...

  8. Python新手学习基础之数据结构-对数据结构的认知

    什么是数据结构? 数据结构是指:相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成. 举个列子来理解这个数据结构: 数据可以比作是书本, 数据结构相当于书架,书存放在书架上, ...

  9. css阴影

    文字阴影:text-shadow:[颜色 x轴 y轴 模糊半径],[颜色 x轴 y轴 模糊半径]... 区域阴影:box-shadow:[颜色 x轴 y轴 模糊半径],[颜色 x轴 y轴 模糊半径]. ...

  10. Scheme是什么、怎么自定义Scheme、JLRoutes的使用-备

    转到移动端开发后居然现在才用到Scheme真是惭愧惭愧. URL Scheme是什么 相信大家都知道URL. http://www.apple.com就是一个URL. 而://之前的部分就称为Sche ...