题目描述

描述 农夫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

说明

翻译来自NOCOW

USACO 2.4

刚读完题,感觉挺简单啊,不过研究了一下样例,一脸懵逼,这咋可能?。

经过机房某位 S型 dalao(son)的解读,哦,so ga si nei,吆西吆西,interisting!!!

再次就借花献佛了。

关于的理解题意:

为了便于理解,这里稍微修改一下题目。

奇数行的栅栏(就是由‘+’和‘-’号组成)将其看做一层类似膜结构,一层防护膜(没有厚度),穿越不占距离。

然后看偶数列,这里需要将偶数列和其两侧的‘-’看做一个整体,亦可以理解为忽略偶数列,只考虑奇数列。

这里拿样例图解:

结合上图,对题意理解就没什么问题了。

解题剖析:

1.读入含空格矩阵:

想了半天,试了多种输入方法,最终貌似只有getline(:不会用戳我啊)可以用。

但是在输入时,需要多输入一行,并且第一行和第二行会重复,其他没毛病,最后貌似没啥大碍。

    scanf("%d%d",&w,&h);
w=w*+;h=h*+;
for(int i=;i<=h+;i++)getline(cin,a[i]);

读入是这样的,若有某位dalao明白以上出现的情况,希望讨论区不吝赐教。

2.字符矩阵转换数字矩阵

在这里定义一个int型map数组。

map[i][j]表示走到这个点需要消耗的距离(偶数行为0,奇数行有空地的话消耗为1)

在字符矩阵中[i][j]这个点为栅栏,不能走,将map[i][j]定义为2.

注意前边说到,输入字符时会有一行多余,所以在转换时处理一下。

此部分代码为:

    for(int i=;i<=h+;i++)
for(int j=;j<w;j++)
{ if(a[i][j]==)
{
if((i-)%==)map[i-][j+]=;
else if((j+)%==)map[i-][j+]=;
else map[i-][j+]=;
}
else map[i-][j+]=;
}

3.初始化:

ans[i][j]数组记录走到 i,j这个点到出口的最近距离,栅栏处直接定义为-1。

void initial()
{
for(int i=;i<=h;i++)
for(int j=;j<=w;j++)
if(map[i][j]==)ans[i][j]=-;
else ans[i][j]=;
}

4.找出出口:

这没啥好说的,四个边找出口(注意经以上过程出口可能为0,可能为1)。

    for(int i=;i<=w;i++)if(map[][i]==||map[][i]==)bfs(,i);
for(int i=;i<=w;i++)if(map[h][i]==||map[h][i]==)bfs(h,i);
for(int i=;i<=h;i++)if(map[i][]==||map[i][]==)bfs(i,);
for(int i=;i<=h;i++)if(map[i][w]==||map[i][w]==)bfs(i,w);

5.大搜索

已经处理处每一格的消耗距离,在搜索时,加上就好啦。

两个出口,需要搜索两边所以搜完注意初始化,bool型数组。

bool vis[N][M];
struct ahah{
int x,y;
}str,cur;
queue <ahah> que;
void bfs(int x,int y)
{
ans[x][y]=;
vis[x][y]=;
str.x=x;str.y=y;
que.push(str);
while(!que.empty())
{
cur=que.front();
que.pop() ;
for(int i=;i<;i++)
{
str.x=cur.x+dx[i];
str.y=cur.y+dy[i];
if(map[str.x][str.y]!=&&str.x>=&&str.x<=h
&&str.y>=&&str.y<=w&&!vis[str.x][str.y])
{
ans[str.x][str.y]=min(ans[cur.x][cur.y]+map[str.x][str.y],ans[str.x][str.y]); vis[str.x][str.y]=;
que.push(str);
}
}
}
memset(vis,,sizeof(vis));
}

6.找出最大值

将ans数组循环一遍,找出最大值,输出即可。

完整代码:

/*.........................
作者:Manjusaka
时间:2018/7/11
题目:P1519 Overfencing
..........................*/ #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
#define N int(100)
#define M int(210)
int dx[]={,,,-},dy[]={,-,,};
string a[N];
int w,h,MAX;
int x[],y[],k;
int map[N][M];
int ans[N][M];
void check();
void _scanf();
void initial();
void bfs(int ,int );
void _scanf()
{
scanf("%d%d",&w,&h);
w=w*+;h=h*+;
for(int i=;i<=h+;i++)getline(cin,a[i]);
for(int i=;i<=h+;i++)
for(int j=;j<w;j++)
{ if(a[i][j]==)
{
if((i-)%==)map[i-][j+]=;
else if((j+)%==)map[i-][j+]=;
else map[i-][j+]=;
}
else map[i-][j+]=;
}
// cout<<"\n";for(int i=1;i<=h;i++){for(int j=1;j<=w;j++){cout<<map[i][j];}cout<<endl;}
check();
}
void check()
{
initial();
for(int i=;i<=w;i++)if(map[][i]==||map[][i]==)bfs(,i);
for(int i=;i<=w;i++)if(map[h][i]==||map[h][i]==)bfs(h,i);
for(int i=;i<=h;i++)if(map[i][]==||map[i][]==)bfs(i,);
for(int i=;i<=h;i++)if(map[i][w]==||map[i][w]==)bfs(i,w);
for(int i=;i<=h;i++)
{
cout<<"\n";
for(int j=;j<=w;j++)
{
printf("%3d",ans[i][j]);
}
}
}
void initial()
{
for(int i=;i<=h;i++)
for(int j=;j<=w;j++)
if(map[i][j]==)ans[i][j]=-;
else ans[i][j]=;
}
bool vis[N][M];
struct ahah{
int x,y;
}str,cur;
queue <ahah> que;
void bfs(int x,int y)
{
ans[x][y]=;
vis[x][y]=;
str.x=x;str.y=y;
que.push(str);
while(!que.empty())
{
cur=que.front();
que.pop() ;
for(int i=;i<;i++)
{
str.x=cur.x+dx[i];
str.y=cur.y+dy[i];
if(map[str.x][str.y]!=&&str.x>=&&str.x<=h
&&str.y>=&&str.y<=w&&!vis[str.x][str.y])
{
ans[str.x][str.y]=min(ans[cur.x][cur.y]+map[str.x][str.y],ans[str.x][str.y]); vis[str.x][str.y]=;
que.push(str);
}
}
}
memset(vis,,sizeof(vis));
}
void _printf()
{
for(int i=;i<=h;i++)
for(int j=;j<=w;j++)
MAX=max(MAX,ans[i][j]);
printf("\n%d",MAX);
}
int main()
{
_scanf();
_printf();
}

求助大佬!!:

按题目要求来说二位数组开到100*200应该完全可以啊,为什么会比RE,求解释。

luogu P1519 穿越栅栏 Overfencing的更多相关文章

  1. 洛谷P1519 穿越栅栏 Overfencing

    P1519 穿越栅栏 Overfencing 69通过 275提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交  讨论  题解 最新讨论 USACO是100分,洛谷是20分 为什么 ...

  2. 【刷题】洛谷 P1519 穿越栅栏 Overfencing

    题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意 ...

  3. 【USACO 2.4.2】穿越栅栏

    [描述] 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找 ...

  4. [luogu P2205] [USACO13JAN]画栅栏Painting the Fence

    [luogu P2205] [USACO13JAN]画栅栏Painting the Fence 题目描述 Farmer John has devised a brilliant method to p ...

  5. [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)

    [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ...

  6. 【luogu P2731 骑马修栅栏】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2731 这个题是欧拉回路的模板题,那么在这里给出一个hierholzer的做法. 对于求欧拉回路的问题,有Fl ...

  7. luogu P2731 骑马修栅栏 Riding the Fences

    入度为奇数的点,搜他. 最好邻接矩阵... #include<cstdio> #include<iostream> #define R register int using n ...

  8. 洛谷P2731 骑马修栅栏 [欧拉回路]

    题目传送门 骑马修栅栏 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经 ...

  9. P2731 骑马修栅栏 (欧拉路径)

    [题目描述] John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一 ...

随机推荐

  1. DFS系列 POJ(自认为的讲解)

    C - Sum It Up POJ1564 题意: 给你一个N,然后给你一堆数The numbers in each list appear in nonincreasing order, and t ...

  2. Visual Studio 的Build Event 使用

    rmdir Configuration mkdir Configuration Copy "$(ProjectDir)Configuration\Spec.config" &quo ...

  3. bzoj 4310: 跳蚤【后缀数组+st表+二分+贪心】

    先求一下SA 本质不同的子串个数是\( \sum n-sa[i]+1-he[i] \),按字典序二分子串,判断的时候贪心,也就是从后往前扫字符串,如果当前子串串字典序大于二分的mid子串就切一下,然后 ...

  4. MapperException: 无法获取实体类xxxxx对应的表名! 三种解决方法,总有一款适合你。

    先把自动重启关一下 devtools: restart: #热部署生效 enabled: false 把devtools给删除了,说是这个jar包导致 ApplyApplication里面的@Mapp ...

  5. 分布式集群环境下,如何实现session共享二(项目开发)

    在上一篇分布式集群环境下,如何实现session共享一(应用场景)中,介绍了在分布式集群下,需要实现session共享的应用场景.并且最后留下了一个问题:在集群环境下,如何实现session的共享呢? ...

  6. SpringAOP和Spring事物管理

    Spring AOP : Pointcut表达式: designators-指示器 wildcards-通配符 operators-操作符 wildcards: * -- 匹配任意数量的字符 + -- ...

  7. python计算代码运行时间的装饰器

    import time def cal_time(func): def wrapper(*args, **kwargs): t1 = time.time() result = func(*args, ...

  8. 洛谷p2922[USACO08DEC]秘密消息Secret Message

    题目: 题目链接:[USACO08DEC]秘密消息Secret Message 题意: 给定n条01信息和m条01密码,对于每一条密码A,求所有信息中包含它的信息条数和被它包含的信息条数的和. 分析: ...

  9. Linux Export命令

    一.Windows 环境变量 1.在Windows 系统下,很多软件安装都需要配置环境变量,比如 安装 jdk ,如果不配置环境变量,在非软件安装的目录下运行javac 命令,将会报告找不到文件,类似 ...

  10. 分享一个实用任意路数PWM函数

    一.什么是PWM? 1.科普一下什么是PWM,嘿嘿,莫闲啰嗦,好好看看,可能大多数人听过,但可能没详细了解过,至此不妨花费几分钟,详细了解哈,PWM中文译名为:脉冲宽度调制,即控制电路在输出频率不变的 ...