luogu P1519 穿越栅栏 Overfencing
题目描述
描述 农夫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个字符表示迷宫
输出格式:
输出一个单独的整数,表示能保证牛从迷宫中任意一点走出迷宫的最小步数。
输入输出样例
5 3
+-+-+-+-+-+
| |
+-+ +-+ + +
| | | |
+ +-+-+ + +
| | |
+-+ +-+-+-+
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的更多相关文章
- 洛谷P1519 穿越栅栏 Overfencing
P1519 穿越栅栏 Overfencing 69通过 275提交 题目提供者该用户不存在 标签USACO 难度普及/提高- 提交 讨论 题解 最新讨论 USACO是100分,洛谷是20分 为什么 ...
- 【刷题】洛谷 P1519 穿越栅栏 Overfencing
题目描述 描述 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意 ...
- 【USACO 2.4.2】穿越栅栏
[描述] 农夫John在外面的田野上搭建了一个巨大的用栅栏围成的迷宫.幸运的是,他在迷宫的边界上留出了两段栅栏作为迷宫的出口.更幸运的是,他所建造的迷宫是一个“完美的”迷宫:即你能从迷宫中的任意一点找 ...
- [luogu P2205] [USACO13JAN]画栅栏Painting the Fence
[luogu P2205] [USACO13JAN]画栅栏Painting the Fence 题目描述 Farmer John has devised a brilliant method to p ...
- [Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增)
[Luogu 5465] [LOJ 6435] [PKUSC2018]星际穿越(倍增) 题面 n个点的图,点i和[l[i],i)的所有点连双向边.每次询问(l,r,x)表示x到[l,r]的所有点的最短 ...
- 【luogu P2731 骑马修栅栏】 题解
题目链接:https://www.luogu.org/problemnew/show/P2731 这个题是欧拉回路的模板题,那么在这里给出一个hierholzer的做法. 对于求欧拉回路的问题,有Fl ...
- luogu P2731 骑马修栅栏 Riding the Fences
入度为奇数的点,搜他. 最好邻接矩阵... #include<cstdio> #include<iostream> #define R register int using n ...
- 洛谷P2731 骑马修栅栏 [欧拉回路]
题目传送门 骑马修栅栏 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经 ...
- P2731 骑马修栅栏 (欧拉路径)
[题目描述] John是一个与其他农民一样懒的人.他讨厌骑马,因此从来不两次经过一个栅栏.你必须编一个程序,读入栅栏网络的描述,并计算出一条修栅栏的路径,使每个栅栏都恰好被经过一次.John能从任何一 ...
随机推荐
- poj1015【DP.......无奈了】
首先,读题,真是一窍不通.后来看完程序的意思,才明白吧.. 题意: n个人中选m个,条件是取sum|D-P|最小,当有|D-P|相同的时候取|D+P|最大的.然后输出那些m个人的sumD,sumP,最 ...
- IT兄弟连 JavaWeb教程 Servlet中定义的变量的作用域类型
在Java语言中,局部变量和实力变量有着不同的作用于,它们的区别如下: 局部变量在一个方法中定义,每当一个线程执行局部变量所在的方法时,在线程的堆栈中就会创建这个局部变量,当线程执行完该方法,局部变量 ...
- 鸟哥私房菜基础篇:Linux是什么习题
猫宁!!! 参考链接:http://cn.linux.vbird.org/linux_basic/0110whatislinux.php#ex 鸟哥是为中国信息技术发展做出巨大贡献的人. 1-你在你的 ...
- TCP协议深度刨析
这篇文章主要是详细说明TCP的拥塞控制,因为它对于我们理解整个TCP/IP协议栈非常重要,但我个人能力有限,其中引用了很多网上其他博主的文章,在下文引用处都有说明,主要是让整篇文章能够连贯,不至于让所 ...
- 2-zakoo使用
source:http://kazoo.readthedocs.io/en/latest/basic_usage.html 1 基本使用 1.1 连接处理 要使用zakoo,需要创建一个KazooCl ...
- _bzoj1096 [ZJOI2007]仓库建设【斜率优化dp】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1096 又是一道经典斜率优化. #include <cstdio> const i ...
- Educational Codeforces Round 18 D
Description T is a complete binary tree consisting of n vertices. It means that exactly one vertex i ...
- JavaScript中简单排序总结
JavaScript中简单排序总结 冒泡排序 经典排序算法, 双重for循环 在第二个for循环的时候, j < arr.len -1 -i , 这一步的优化很重要 function bullS ...
- magento 自定义url路径 和 filter data 小结
背景是往一个第三方的搜索插件里面加入filter功能. 首先是路径,插件自己定义了一个router,类似于cms.那首先说说router好了,从入口一路追查的话,会发现最后进入的是Mage_Core_ ...
- 为页面添加favicon
<link rel="shortcut icon" href="favicon.ico" /> 还有另一种写法,但是IE对它的支持不够好: < ...