题目描述

描述 农夫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. 探究final在java中的作用

    目录 一. final修饰变量 1. 基础: final修饰基本数据类型变量和引用数据类型变量. 2. 进阶: 被final修饰的常量在编译阶段会被放入常量池中 3. 探索: 为什么局部/匿名内部类在 ...

  2. (4)ASP.NET Core 中间件

    1.前言 整个HTTP Request请求跟HTTP Response返回结果之间的处理流程是一个请求管道(request pipeline).而中间件(middleware)则是一种装配到请求管道以 ...

  3. 如何实现session的共享?

    1.以cookie加密的方式保存在客户端. 优点是减轻服务器端的压力 缺点是受到cookie的大小限制,可能占用一定带宽,因为每次请求会在头部附带一定大小的cookie信息,另外这种方式在用户禁止使用 ...

  4. 51nod1266【水】

    最短,两半分开走 最长,一边走,比较一下两端就好了. #include <bits/stdc++.h> using namespace std; typedef long long LL; ...

  5. 51nod 1004 【快速幂】

    思路: 掐住最后一位,快速幂一发就好了 #include<cstdio> #include <map> #include<iostream> #include< ...

  6. BFS+PRIM

    转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1299324104 在一个y行 x列的迷宫中,有可行走的通路空格' ',不可行走的墙'#', ...

  7. 键值观察 KVO

    http://www.cnblogs.com/dyf520/p/3805297.html Key-Value Observing Programming Guide 1,注册Key-Value Obs ...

  8. Centos 配置 Mysql 主从双向同步

    配置之前,请先阅读mysql主从复制: Mysql-主从复制 原:  主从环境: 主服务器:192.168.153.130 从服务器:192.168.153.131 1.从数据库创建同步用户,将主数据 ...

  9. Android课程设计第一天Android Studio安装

    注意:课程设计只为完成任务,不做细节描述~ 学校有一个Android的课设,所以顺便把Android Studio安装了上去. 实际上安装过程并不复杂,只有几个地方需要注意~ 安装包可以去http:/ ...

  10. [转]Linq 如何实现 in 与 not in

    本文转自:http://blog.csdn.net/zhangyumei/article/details/5620363 接触 LINQ 也有很长的一段时间了,有些在 SQL 语句中用的很顺手的东西在 ...