洛谷P1301 魔鬼之城 题解
想找原题请点击这里:传送门
题目描述
在一个被分割为N*M个正方形房间的矩形魔鬼之城中,一个探险者必须遵循下列规则才能跳跃行动。他必须从(, )进入,从(N, M)走出;在每一房间的墙壁上都写了一个魔法数字,是1~13之内的自然数;探险者可以想像出8个方向中的任何一个(水平或垂直或对角线方向),随后他就可以作一次空间跳跃穿过这一方向上的连续的X个房间,其中X是他原来所在房间的魔法数字。但如果在这一方向上的房间数小于X,则他不作任何跳跃,而必须想像另一个方向。同时,探险者不能作连续两次相同方向的跳跃。 例如在上图的5*4的魔鬼之城中,如果探险者现在所在的位置是(, ),那么通过依次空间跳跃他可以到达下列房间中的一个:(, ),(, ),(, ),(, ),或(, )。另外,如果他要用两次跳跃从(, )到达(, ),则他不能首先跳到(, )(因为这样他第二次跳跃的方向将和第一次相同,而这是不允许的)。所以他必须先跳跃到(, )。 请你写一个程序,对给定的地图,算出探险者至少需要跳跃多少步才能离开魔鬼之城。 输入格式
一行给出N,M(都不超过100); 下来有M行,每行为N个自然数,表示对应房间中的魔法数字。 输出格式
出最小步数,如果探险者无法离开魔鬼之城,请输出“NEVER”。 输入输出样例
输入 #1复制 输出 #1复制
(图片请自行到原网站查看)
这道题乍一看跟迷宫最短路径问题很相似所以初步印象首选bfs,然后我们做进一步分析:
我们经过分析又得知两次不可能连续走同一方向,所以我们在进行bfs时还需要定义一变量记录上一步跳跃方向以防止连续两次方向相同。
我们经过分析又得知如果同一个点在bfs过程中被访问了两次相同方向,那么这一行为必定是没有贡献的(相当于走了一遍走过的路所以也就不需要重新走一遍了)
所以基于上述分析我们可得知我们可以对每一个点的八个不同方向建立bool数组来记录是否被访问过。
代码实现:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[][];
bool b[][][];
int ans=-;
int t; //多少步
int vis; //多少个格子被访问
int v; //这一个格子上的数
struct node{
int x;
int y;
int direct; //1表示向左上然后逆时针
};
node tmp;
queue < pair<node,int> > q;
void bfs(int xx,int yy){
q.push(make_pair((node){xx,yy,},));
while(!q.empty()){
tmp=q.front().first;
t=q.front().second;
q.pop();
if(tmp.x==n&&tmp.y==m) {ans=t;break;}
if(b[tmp.x][tmp.y][tmp.direct]) continue;
b[tmp.x][tmp.y][tmp.direct]=true;
vis++;
v=a[tmp.x][tmp.y];
if(tmp.x-v>=){
if(tmp.y-v>=&&!b[tmp.x-v][tmp.y-v][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x-v,tmp.y-v,},t+));
vis++;
}
if(tmp.y+v<=m&&!b[tmp.x-v][tmp.y+v][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x-v,tmp.y+v,},t+));
vis++;
}
if(!b[tmp.x-v][tmp.y][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x-v,tmp.y,},t+));
vis++;
}
}
if(tmp.x+v<=n){
if(tmp.y+v<=m&&!b[tmp.x+v][tmp.y+v][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x+v,tmp.y+v,},t+));
vis++;
}
if(tmp.y-v>=&&!b[tmp.x+v][tmp.y-v][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x+v,tmp.y-v,},t+));
vis++;
}
if(!b[tmp.x+v][tmp.y][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x+v,tmp.y,},t+));
vis++;
}
}
if(tmp.y-v>=&&!b[tmp.x][tmp.y-v][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x,tmp.y-v,},t+));
vis++;
}
if(tmp.y+v<=m&&!b[tmp.x][tmp.y+v][]&&tmp.direct!=){
q.push(make_pair((node){tmp.x,tmp.y+v,},t+));
vis++;
}
}
return ;
}
int main(){
scanf("%d%d",&n,&m);
for(register int i=;i<=m;i++){
for(register int j=;j<=n;j++){
scanf("%d",&a[j][i]);
}
}
bfs(,);
if(ans>){
printf("%d",ans);
}
else{
printf("NEVER");
}
return ;
}
洛谷P1301 魔鬼之城 题解的更多相关文章
- 洛谷 P1301 魔鬼之城
P1301 魔鬼之城 题目描述 在一个被分割为N*M个正方形房间的矩形魔鬼之城中,一个探险者必须遵循下列规则才能跳跃行动.他必须从(1, 1)进入,从(N, M)走出:在每一房间的墙壁上都写了一个魔法 ...
- 洛谷P1301 魔鬼之城
传送门啦 一道广度优先搜索的题目. 结构体含义: struct node{ int x,y,dir;//坐标,方向 int step;//当前步数 }; 方向的标号受上面定义的 $ dx[ ] , d ...
- 洛谷P1783 海滩防御 分析+题解代码
洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...
- 洛谷P1514 引水入城
洛谷P1514 引水入城 原题链接 一道好题...细节真多 第一次提交90分,然后就GG了,不知从何改起 其实比较简单吧... 首先,一个点的水流向最后一排,一定可以形成一个区间. 不行的话肯定GG ...
- 洛谷P4047 [JSOI2010]部落划分题解
洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...
- 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)
洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...
- 洛谷10月月赛II题解
[咻咻咻] (https://www.luogu.org/contestnew/show/11616) 令人窒息的洛谷月赛,即将参加NOIp的我竟然只会一道题(也可以说一道也不会),最终145的我只能 ...
- [洛谷P1823]音乐会的等待 题解(单调栈)
[洛谷P1823]音乐会的等待 Description N个人正在排队进入一个音乐会.人们等得很无聊,于是他们开始转来转去,想在队伍里寻找自己的熟人.队列中任意两个人A和B,如果他们是相邻或他们之间没 ...
- BZOJ2527 & 洛谷3527:[Poi2011]Meteors——题解
+++++++++++++++++++++++++++++++++++++++++++ +本文作者:luyouqi233. + +欢迎访问我的博客:http://www.cnblogs.com/luy ...
随机推荐
- Django中的check指令和sqlmigrate指令
官方文档的解释如下: Django 有一个自动执行数据库迁移并同步管理你的数据库结构的命令 - 这个命令是 migrate,我们马上就会接触它 - 但是首先,让我们看看迁移命令会执行哪些 SQL 语句 ...
- codeforces 1245D(最小生成树)
题面链接:https://codeforces.com/problemset/problem/1245/D 题意大概是给你一些城市的坐标,可以在城市中建立发电站,也可以让某个城市和已经建好发电站的城市 ...
- Redis如果内存满了怎么办?
Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 ...
- 8.10-Day2T3 镇守府
emm IOI原题(洛谷,bzoj都有) 其实并没有怎么搞懂dp方程转移那部分 就...粘个(抄来的)代码过来吧 #include<bits/stdc++.h> using namespa ...
- 6_11 四分树(UVa297)<四分树>
一幅图有1024个点, 可以对图平均分成4块, 并且子图也可以再往下分, 直到一个子图表示一个点. f表示这块子图填满, p表示它还有4个子图, e表示没有子图(当然啦, 它也没有填满). 给定两个字 ...
- 当map的key为对象时,js无法解析key的属性值
重写对象的toString方法,按照json数据的规则 然后前台string转json 控制台打印 这个方法不需要引入其他包 如果map的key属性过多,或者key是集合,可以在后台先转json,然后 ...
- 使用SQL命令行更改数据库字段类型
ALTER TABLE 表名 MODIFY COLUMN 字段名 数据类型 添加列 ALTER TABLE students ADD COLUMN address VARCHAR(100) DEFAU ...
- Good Bye 2019E(点坐标缩小一半以区分奇偶性)
设某个点的坐标为(x,y),根据坐标奇偶性公可分为四类,0表示偶数,1表示奇数,(0,0),(0,1),(1,0),(1,1). 如果所有点的坐标都属于一类,那么它们之间的距离都是4的倍数,无法分辨. ...
- 每天进步一点点------基础实验_08_触发器 :D、T触发器各一
/********************************************************************************* * Company : * Eng ...
- javaScript中的querySelector和querySelectorAll
querySelector和querySelectorAll是W3C提供的 新的查询接口,其主要特点如下: 1.querySelector只返回匹配的第一个元素,如果没有匹配项,返回null. 2.q ...