[USACO2.4]穿越栅栏 Overfencing
2017-07-28 12:46
447 查看
题目描述
描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫。幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口。更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找到一条走出迷宫的路。给定迷宫的宽度W(1<=W<=38)及高度H(1<=H<=100)。 2*H+1行,每行2*W+1的字符以下面给出的格式表示一个迷宫。然后计算从迷宫中最“糟糕”的那一个点走出迷宫所需的步数(就是从最“糟糕”的一点,走出迷宫的最少步数)。(即使从这一点以最优的方式走向最靠近的出口,它仍然需要最多的步数)当然了,牛们只会水平或垂直地在X或Y轴上移动,他们从来不走对角线。每移动到一个新的方格算作一步(包括移出迷宫的那一步)这是一个W=5,H=3的迷宫:+-+-+-+-+-+
| | +-+ +-+ + +
| | | |
+-+-+ + +
| | |
+-+ +-+-+-+
(请将上图复制到记事本观看更加)
如上图的例子,栅栏的柱子只出现在奇数行或奇数列。每个迷宫只有两个出口。
输入输出格式
输入格式:第一行: W和H(用空格隔开)
第二行至第2 H + 1行: 每行2 W + 1个字符表示迷宫
输出格式:
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
输入输出样例
输入样例#1:5 3 +-+-+-+-+-+ | | +-+ +-+ + + | | | | + +-+-+ + + | | | +-+ +-+-+-+
输出样例#1:
9
4000
说明
翻译来自NOCOWUSACO 2.4
【题解】
通常的,最短路用广度优先搜索
/*
ID:luojiny1
LANG:C++
TASK:maze1
*/
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=100*2+100,maxm=38*2+100;
bool up[maxn][maxm]={0},down[maxn][maxm]={0},left[maxn][maxm]={0},right[maxn][maxm]={0},done[maxn][maxm];
int m,n,d[maxn][maxm],ans=0;
char str[maxn][maxm];
bool ok(char ch)
{
return ch=='+'||ch=='-'||ch=='|';
}
struct Node{
int i,j,step;
};
void bfs(int i,int j){
queue<Node>Q;
Q.push((Node){i,j,1});
while(!Q.empty())
{
Node u=Q.front();Q.pop();
if(done[u.i][u.j])continue;
done[u.i][u.j]=true;
if(d[u.i][u.j]>u.step)d[u.i][u.j]=u.step;
if(up[u.i][u.j]==0&&u.i-1>=0)Q.push((Node){u.i-1,u.j,u.step+1});
if(right[u.i][u.j]==0&&u.j+1<m)Q.push((Node){u.i,u.j+1,u.step+1});
if(down[u.i][u.j]==0&&u.i+1<n)Q.push((Node){u.i+1,u.j,u.step+1});
if(left[u.i][u.j]==0&&u.j-1>=0)Q.push((Node){u.i,u.j-1,u.step+1});
}
}
int main()
{
freopen("maze1.in","r",stdin);
freopen("maze1.out","w",stdout);
memset(d,0x7f,sizeof(d));
scanf("%d%d\n",&m,&n);
for(int i=0;i<2*n+1;i++){
for(int j=0;j<2*m+1;j++){
char ch=getchar();
str[i][j]=ch;
} getchar();}
for(int i=1;i<=n*2-1;i+=2)
for(int j=1;j<=m*2-1;j+=2){
if(ok(str[i-1][j]))up[i/2][j/2]=1;
if(ok(str[i][j+1]))right[i/2][j/2]=1;
if(ok(str[i+1][j]))down[i/2][j/2]=1;
if(ok(str[i][j-1]))left[i/2][j/2]=1;
}
for(int i=0;i<m;i++)
if(up[0][i]==0){
memset(done,0,sizeof(done));
bfs(0,i);
}
for(int i=0;i<n;i++){
if(left[i][0]==0){
memset(done,0,sizeof(done));
bfs(i,0);
}
if(right[i][m-1]==0){
memset(done,0,sizeof(done));
bfs(i,m-1);
}
}
for(int i=0;i<m;i++)
if(down[n-1][i]==0){
memset(done,0,sizeof(done));
bfs(n-1,i);
}
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)if(d[i][j]>ans)ans=d[i][j];
printf("%d\n",ans);
return 0;
}
相关文章推荐
- 【USACO题库】2.4.2 Overfencing穿越栅栏
- usaco2.4.3穿越栅栏(最短路)
- 【USACO2.4.2】穿越栅栏 BFS爆搜
- luogu P1519 穿越栅栏 Overfencing
- USACO 2.4.2 穿越栅栏(原题) 解题报告
- 【USACO 2.4.2】穿越栅栏
- USACO - 2.4.2 穿越栅栏(改编) 重庆一中高2018级竞赛班第二次测试 2016.7.13 Problem 3
- P1519 穿越栅栏 Overfencing
- Luogu P1519 穿越栅栏 Overfencing
- 【USACO2.4.2】穿越栅栏
- usaco Overfencing 穿越栅栏(BFS)
- USACO2.4.2 穿越栅栏(简单版本) (重庆一中高2018级信息学竞赛测验2) 解题报告
- USACO2.4.2 穿越栅栏
- 【7.13第三题】穿越栅栏【USACO2.4.2简单版本】
- 【搜索】洛谷 P1519 穿越栅栏 Overfencing
- Overfencing 穿越栅栏
- 洛谷P1519 穿越栅栏 Overfencing
- USACO 2.4 Overfencing
- USACO 2.4.2 穿越栅栏
- USACO 2.4.2改 穿越栅栏(多源bfs)