2023集 bfs3 P2864 [USACO06JAN] The Grove S

[USACO06JAN] The Grove S

题目描述

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.

牧场里有树林,林子里没有坑,贝茜很想知道,最少几步能绕树林走一圈,最后回到起点.她能上下左右走,也能走对角线格子.

牧场被分成 R R R C C C ( 1 ≤ R ≤ 50 ,   1 ≤ C ≤ 50 ) (1\leq R\leq 50,\ 1\leq C\leq 50) (1R50, 1C50) 。下面是一张样例的地图,其中 . 表示贝茜可以走的空地, X 表示树林,表示起点.而贝茜走的最近的路已经特别地用 + 表示 出来.

题目保证存在最短路径,且森林形成一个联通块。

输入格式

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).

输出格式

Line 1: The single line contains a single integer which is the smallest number of steps required to circumnavigate the grove.

样例 #1

样例输入 #1

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

样例输出 #1

11

思路

要绕一个圈形成最短路径,可以把这个圈化为向左或者向右多条路径来计算
根据这个想法,可以在这个连通块上取一点,这里我采用找到整个连通块的最低点
在这个点上以这个点为起点取一条向下射线,在这个点的右方也取一条向下的射线
不难想到,从起点开始,走到左端射线的点最短的路径加上走到右端的点最短的路径以及两点之间的距离即为答案(注意只能是能走的的点之间相互为一对)
如图在这里插入图片描述

完整代码

#include<bits/stdc++.h>
using namespace std;
int n,m,p,q;
struct stu{
	int x,y,step;
};
queue<stu> qu;
const int dx[]={-1,-1,-1,0,0,1,1,1};
const int dy[]={-1,0,1,-1,1,-1,0,1};
char mp[100][100];
int vis[100][100];
void bfs()
{
	while(!qu.empty())
	{
		stu f=qu.front();qu.pop();
		for(int i=0;i<8;i++)
		{
			int x1=f.x+dx[i],y1=f.y+dy[i];
			if(f.y==q&&f.x>=p&&(i==2||i==4||i==7))continue;
			//如果在最低点的射线上就不可以向右走
			if(f.y==q+1&&f.x>=p&&(i==0||i==3||i==5))continue;
			//如果在最低点右边的射线上就不可以向左走
			//注意这两行是要已经被记录的状态查看是否在线上,不是欲到达的状态
			//欲到达的状态可以向下走或者向上走
			if(mp[x1][y1]=='.'&&vis[x1][y1]==-1)
			{
				vis[x1][y1]=vis[f.x][f.y]+1;//记录步数
				qu.push({x1,y1,f.step+1});//加入状态
			}
		}	
	}
}
int main()
{
	memset(vis,-1,sizeof(vis));
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>mp[i][j];
			if(mp[i][j]=='*')
			{
				qu.push({i,j,0});
				vis[i][j]=0;
			}//找到起点并加入状态
			if (mp[i][j]=='X') p=i,q=j;//找到整张图的最低点	
		}
	}
	bfs();
	int ans=1<<30;
	for(int i=p+1;i<=n;i++)
		for(int j=-1;j<=1;j++)
			if(vis[i][q]!=-1&&vis[i+j][q+1]!=-1)
				ans=min(ans,vis[i][q]+vis[i+j][q+1]+1);//最后把这些路径连接起来
    cout<<ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值