博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P1825 [USACO11OPEN]玉米田迷宫Corn Maze
阅读量:6112 次
发布时间:2019-06-21

本文共 3482 字,大约阅读时间需要 11 分钟。

题目描述

去年秋天,奶牛们去参观了一个玉米迷宫,迷宫里有一些传送装置,可以将奶牛从一点到另一点进行瞬间转移。这些装置可以双向使用:一头奶牛可以从这个装置的起点立即到此装置的终点,同时也可以从终点出发,到达这个装置的起点。如果一头奶牛处在这个装置的起点或者终点,这头奶牛就必须使用这个装置。

玉米迷宫的外部完全被玉米田包围,除了唯一的一个出口。

这个迷宫可以表示为N×M的矩阵(2 ≤ N ≤ 300; 2 ≤ M ≤ 300),矩阵中的每个元素都由以下项目中的一项组成:

1、 玉米,这些格子是不可以通过的。

2、 草地,可以简单的通过。

3、 一个装置的结点,可以将一头奶牛传送到相对应的另一个结点。

4、出口

奶牛仅可以在相邻两个格子之间移动,要在这两个格子不是由玉米组成的前提下才可以移动。奶牛能在一格草地上可能存在的四个相邻的格子移动。从草地移动到相邻的一个格子需要花费一个单位的时间,从装置的一个结点到另一个结点需要花费0个单位时间。

被填充为玉米的格子用“#”表示,草地用“.”表示,每一对装置的结点由相同的大写字母组成“A-Z”,且没有两个不同装置的结点用同一个字母表示,出口用“=”表示。

Bessie在这个迷宫中迷路了,她知道她在矩阵中的位置,将Bessie所在的那一块草地用“@”表示。求出Bessie需要移动到出口处的最短时间。

例如以下矩阵,N=5,M=6:

###=###.W.###.#####.@W########

唯一的一个装置的结点用大写字母W表示。

最优方案为:先向右走到装置的结点,花费一个单位时间,再到装置的另一个结点上,花费0个单位时间,然后再向右走一个,再向上走一个,到达出口处,总共花费了3个单位时间。

输入输出格式

输入格式:

 

第一行:两个用空格隔开的整数N和M;

第2-N+1行:第i+1行描述了迷宫中的第i行的情况(共有M个字符,每个字符中间没有空格。)

 

输出格式:

 

一个整数,表示Bessie到达终点所需的最短时间。

 

输入输出样例

输入样例#1: 
5 6###=###.W.###.#####.@W########
输出样例#1: 
3 分析 走迷宫加强版,每次多了瞬间传送的情况,注意判断细节即可(第一次写的时候竟然以为只有一个传送门W 23333). 其实我debug了一小时 wwx你要补偿我,肉偿 代码
#include
using namespace std;char mp[1000][1000];int book[1000][1000];int n,m;int beginx,beginy;int move_beginx[30];int move_beginy[30];int move_endy[30];int move_endx[30];int changex[5]={
0,0,1,0,-1};int changey[5]={
0,1,0,-1,0};struct Point{ int x; int y; int step; Point(int _x,int _y,int _step): x(_x),y(_y),step(_step){}//构造函数 };queue
q;int ans;int flag[30];int main(){// freopen("testdata.in","r",stdin); cin>>n>>m; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { cin>>mp[i][j]; if(mp[i][j]=='@') { beginx=i; beginy=j; } if(mp[i][j]>='A'&&mp[i][j]<='Z') { if(flag[mp[i][j]-'A']==0) { flag[mp[i][j]-'A']=1; move_beginx[mp[i][j]-'A']=i; move_beginy[mp[i][j]-'A']=j; } else { move_endx[mp[i][j]-'A']=i; move_endy[mp[i][j]-'A']=j; } }//存储传送门 } } q.push(Point(beginx,beginy,0)); book[beginx][beginy]=1;//记得起点标记 while(!q.empty()) { Point now_node=q.front(); q.pop(); int now_x=now_node.x; int now_y=now_node.y;// cout<
<<" "<
<<" "<
<
n||new_x<1) continue; if(new_y>m||new_y<1) continue; if(mp[new_x][new_y]=='#') continue; if(book[new_x][new_y]==1) continue; book[new_x][new_y]=1; if(mp[new_x][new_y]=='=') { ans=now_step+1; goto u; }//搜到答案 if(mp[new_x][new_y]>='A'&&mp[new_x][new_y]<='Z')//提前打了标记不会存在传来传去的情况 { if((new_x==move_beginx[mp[new_x][new_y]-'A'])&&(new_y==move_beginy[mp[new_x][new_y]-'A'])) { if(move_endx[mp[new_x][new_y]-'A']==0) continue; int jump_x=move_endx[mp[new_x][new_y]-'A']; int jump_y=move_endy[mp[new_x][new_y]-'A']; q.push(Point(jump_x,jump_y,now_step+1)); }//传送门其中一端 else if((new_x==move_endx[mp[new_x][new_y]-'A'])&&(new_y==move_endy[mp[new_x][new_y]-'A'])) { if(move_beginx[mp[new_x][new_y]-'A']==0) continue; int jump_x=move_beginx[mp[new_x][new_y]-'A']; int jump_y=move_beginy[mp[new_x][new_y]-'A'];//不知道为什么直接赋值给new_x会挂,新开了个变量 q.push(Point(jump_x,jump_y,now_step+1)); }//另一端 }//是传送门 else { q.push(Point(new_x,new_y,now_step+1)); }//不是传送门 } } u:cout<
<
 

 

 

转载于:https://www.cnblogs.com/KyleDeng/p/9902228.html

你可能感兴趣的文章
B1010.一元多项式求导(25)
查看>>
10、程序员和编译器之间的关系
查看>>
前端学习之正则表达式
查看>>
配置 RAILS FOR JRUBY1.7.4
查看>>
AndroidStudio中导入SlidingMenu报错解决方案
查看>>
修改GRUB2背景图片
查看>>
Ajax异步
查看>>
好记性不如烂笔杆-android学习笔记<十六> switcher和gallery
查看>>
JAVA GC
查看>>
codeforce 599B Spongebob and Joke
查看>>
3springboot:springboot配置文件(外部配置加载顺序、自动配置原理,@Conditional)
查看>>
9、Dubbo-配置(4)
查看>>
前端第七天
查看>>
BZOJ 2190[SDOI2008]仪仗队
查看>>
图解SSH原理及两种登录方法
查看>>
[转载] 七龙珠第一部——第058话 魔境圣地
查看>>
【总结整理】JQuery基础学习---样式篇
查看>>
查询个人站点的文章、分类和标签查询
查看>>
基础知识:数字、字符串、列表 的类型及内置方法
查看>>
JSP的隐式对象
查看>>