2855 游乐园的迷宫

 时间限制: 1 s    空间限制: 128000 KB    题目等级 : 黄金 Gold
题目描述 Description

迷宫可是每个游乐园必不可少的项目,菜菜当然是要尝试一下啦。

这个迷宫比较特殊。与其说是迷宫,倒不如说是一个巨大的格子。游乐园给菜菜发了一张地图,地图上标明了,这个格子由n行m列共n*m个小格子组成。有的格子可以正常走,标为’.’;有的格子有陷阱不能走,标为‘#’;有的格子比较特殊,标为‘*’,可以向周围八个方向可走的格子走一格;目的地标记为‘@’。菜菜从左上角处开始,并且可以按中国象棋中的马和象的方式或者特殊格的八方向来走。如果按照最短的路径到达目的地,则可以获得奖励。

菜菜当然想获得奖励啦,于是就来找你帮忙,请你帮忙计算最少需要多少步。

输入描述 Input Description

第一行,两个正整数n,m。

接下来的n行m列描述了地图。

输出描述 Output Description

一个整数,表示所要走的最小步数。若无法到达目的地则输出-1。

样例输入 Sample Input

11 10

..........

....#.....

..........

...#.*....

.......*..

..#..#...@

*.........

...#...#..

.....*....

...#......

..*....*..

样例输出 Sample Output

13

数据范围及提示 Data Size & Hint

对于20%的数据,保证0<n,m≤20

对于100%的数据,保证0<n,m≤200

50分代码存档:

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define maxn 205
int n,m,dis[maxn][maxn],ex,ey;
int dx[]={-,-,-,-,-,-,+,+,+,+,+,+};
int dy[]={-,-,+,-,+,+,-,+,-,-,+,+};
int bax[]={-,-,-,,,,,};
int bay[]={-,,,-,,-,,};
char map[maxn][maxn];
queue<int> stx,sty;
bool vis[maxn][maxn];
bool Judge(int xx,int yy){
if(xx>&&xx<=n&&yy>&&yy<=m&&map[xx][yy]!='#'&&!vis[xx][yy])
return true;
else return false;
}
void BFS(){
stx.push();sty.push();
while(!stx.empty()){
int nx=stx.front(),ny=sty.front();
stx.pop();sty.pop();
if(map[nx][ny]=='.'){
for(int i=;i<;i++){
int xx=nx+dx[i],yy=ny+dy[i];
if(Judge(xx,yy)){
stx.push(xx);sty.push(yy);vis[xx][yy]=true;
dis[xx][yy]=min(dis[xx][yy],dis[nx][ny]+);
if(xx==ex&&yy==ey) return;
}
}
}
else if(map[nx][ny]=='*'){
for(int i=;i<;i++){
int xx=nx+dx[i],yy=ny+dy[i];
if(Judge(xx,yy)){
stx.push(xx);sty.push(yy);vis[xx][yy]=true;
dis[xx][yy]=min(dis[xx][yy],dis[nx][ny]+);
if(xx==ex&&yy==ey) return;
}
}
}
}
}
int main()
{
memset(dis,0x3f,sizeof(dis));
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
cin>>map[i][j];
if(map[i][j]=='@') ex=i,ey=j;
}
dis[][]=;
BFS();
if(dis[ex][ey]==0x3f) printf("-1\n");
else printf("%d\n",dis[ex][ey]);
return ;
}

AC代码:

 #include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxN = ;
char maze[maxN][maxN];
int n,m;
int dx,dy;
bool vis[maxN][maxN];
struct Node {
int x,y;
int dep;//记录步数
};
bool is_raw(int x,int y) {
if(x >= && x <= n && y >= && y <= m && maze[x][y] != '#') return true;
return false;
}
bool ok = false;
int dir[]= {,,,-, -,,-,-, ,,,-, -,-,-,, //马
,-,-,,-,-,,};//象
int spec[] = {-,,-,-,-,, ,-,,,,, ,,,-};//九宫格
int ans = ;
void bfs() { //找最小,宽搜罗~
Node start;
start.x = , start.y = ;
start.dep = ;
queue<Node> q;
q.push(start);
while(!q.empty()) {
Node head = q.front();
//printf("x is %d, y is %d , dep is %d \n",head.x,head.y,head.dep);
if(head.x == dx && head.y == dy) {
ok = true;
ans = head.dep;
return;
}
q.pop();
for(int i = ; i < ; i = i + ) {
if(is_raw(head.x+dir[i],head.y+dir[i+])&&
!vis[head.x+dir[i]][head.y+dir[i+]]) {
Node one;
vis[head.x+dir[i]][head.y+dir[i+]] = true;
one.x = head.x+dir[i];
one.y = head.y+dir[i+];
one.dep = head.dep+;
q.push(one);
}
}
if(maze[head.x][head.y] == '*') {
for(int i = ; i < ; i = i + ) {
if(is_raw(head.x+spec[i],head.y+spec[i+])&&
!vis[head.x+spec[i]][head.y+spec[i+]]) {
Node one;
vis[head.x+spec[i]][head.y+spec[i+]] = true;
one.x = head.x+spec[i];
one.y = head.y+spec[i+];
one.dep = head.dep+;
q.push(one);
}
}
}
}
}
int main() {
cin>>n>>m;
memset(vis,,sizeof(vis));
for(int i = ; i <= n ; i++) {
for(int j = ; j <= m; j++) {
cin>>maze[i][j];
if(maze[i][j] == '@')
dx = i,dy = j;
}
}
//printf("目标是 %d %d\n",dx,dy);
bfs();
if(ok) printf("%d\n",ans);
else cout<<"-1"<<endl;
}

//话说这题样例有问题,被样例坑了好长时间.......

再次AC代码:

/*
再次AC代码。。我日,我说咋回事吗,我感觉我写的也没什么
毛病就是不对挨!原来是题意理解错误 对于那些特殊的点既能够
按照八方向来走 ,也能够按照 普通点的 方向来走,刚开始写的时候
把两类点分开 写的。。。
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
#define maxn 205
int n,m,dis[maxn][maxn],ex,ey;
int dx[]={-2,-2,-2,-2,-1,-1,+1,+1,+2,+2,+2,+2};
int dy[]={-2,-1,+1,-2,+2,+2,-2,+2,-2,-1,+1,+2};
int bax[]={-1,-1,-1,0,0,1,1,1};
int bay[]={-1,0,1,-1,1,-1,0,1};
char map[maxn][maxn];
queue<int> stx,sty;
bool vis[maxn][maxn];
bool Judge(int xx,int yy){
if(xx>0&&xx<=n&&yy>0&&yy<=m&&map[xx][yy]!='#'&&!vis[xx][yy])
return true;
else return false;
}
void BFS(){
stx.push(1);sty.push(1);
while(!stx.empty()){
int nx=stx.front(),ny=sty.front();
stx.pop();sty.pop();
for(int i=0;i<12;i++){
int xx=nx+dx[i],yy=ny+dy[i];
if(Judge(xx,yy)){
stx.push(xx);sty.push(yy);vis[xx][yy]=true;
dis[xx][yy]=min(dis[xx][yy],dis[nx][ny]+1);
if(xx==ex&&yy==ey) return;
}
}
if(map[nx][ny]=='*'){
for(int i=0;i<8;i++){
int xx=nx+dx[i],yy=ny+dy[i];
if(Judge(xx,yy)){
stx.push(xx);sty.push(yy);vis[xx][yy]=true;
dis[xx][yy]=min(dis[xx][yy],dis[nx][ny]+1);
if(xx==ex&&yy==ey) return;
}
}
}
}
}
int main()
{
memset(dis,0x3f,sizeof(dis));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
cin>>map[i][j];
if(map[i][j]=='@') ex=i,ey=j;
}
dis[1][1]=0;
BFS();
if(dis[ex][ey]>=1500000) printf("-1\n");
else printf("%d\n",dis[ex][ey]);
return 0;
}

  

Codevs 2855 游乐园的迷宫的更多相关文章

  1. Codevs 1337 银行里的迷宫

    1337 银行里的迷宫 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 传送门 题目描述 Description 楚楚每一次都在你的帮助下过了一关又一关(比如他开 ...

  2. codevs——3344 迷宫

    3344 迷宫  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 小刚在迷宫内,他需要从A点出发,按顺序经过B, ...

  3. codevs 3344 迷宫

    时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold 题目描述 Description 小刚在迷宫内,他需要从A点出发,按顺序经过B,C,D……,到达最后一个点,再回到A ...

  4. codevs——T1337 银行里的迷宫

     时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题解       题目描述 Description 楚楚每一次都在你的帮助下过了一关又一关(比如他开宴会). ...

  5. Codevs 1629 01迷宫

    1629 01迷宫 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 有一个由01组成的n*n格迷宫,若你位于一格0上,那么你可 ...

  6. codevs 1215 迷宫

    时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题目描述 Description 已知 n 个整数 x1,x2,-,xn,以及一个整数 k(k<n).从 n ...

  7. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  8. codevs 2822 爱在心中

    codevs 2822 爱在心中  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description “每个人都拥有一个梦,即使彼此不相同, ...

  9. 逃出克隆岛 (codevs 2059)

    较普通的走迷宫的题 传送门 :codevs 2059 逃出克隆岛 思路 :BFS 即可    PS :传送门 不必重复使用 #include <iostream> #include < ...

随机推荐

  1. sparkmlib-相关系数

    一.基本原理 在stat包中实现了皮尔逊(Pearson)与 斯皮尔曼(Spearman)两类相关系数的计算 (1)Pearson:   (x,y)协方差/[(x标准方差)*(y标准方差)] 详情可以 ...

  2. Dockerfile优化建议

    1. 减少镜像层 一次RUN指令形成新的一层,尽量Shell命令都写在一行,减少镜像层. 2. 优化镜像大小:清理无用数据 一次RUN形成新的一层,如果没有在同一层删除,无论文件是否最后删除,都会带到 ...

  3. https 调用验证失败 peer not authenticated

    https 调用验证失败 peer not authenticated 报错日志: Caused by: javax.net.ssl.SSLPeerUnverifiedException: peer ...

  4. shell脚本,用awk实现替换文件里面的内容。

    文件是这样,有ID和具体信息,ID行以@开头,后面的信息有空格,把第一个空格后的全部内容替换为空格前的字符. 用AWK来实现. @AA10 P 7 #YYYYYYYYYYYYYYYYYYZZZZZZZ ...

  5. lucene测试类

    package test.lucene; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStrea ...

  6. CS193p Lecture 10 - Multithreating, UIScrollView

    Multithreating(多线程) 网络请求例子: NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithStrin ...

  7. JS与IOS、安卓的交互

    最近做的项目中涉及到了与安卓和ios的交互问题,对于一个新手来说,多多少少会有点迷糊.在调用安卓和ios的callback回调时,很轻松的就调用成功了,而且,步骤也不那么繁琐.刚开始,只知道那样使用可 ...

  8. linux配置MySql表名不区分大小写

    1.Linux下mysql安装完后是默认:区分表名的大小写,不区分列名的大小写:2.用root帐号登录后,在/etc/my.cnf中的[mysqld]后添加添加lower_case_table_nam ...

  9. python-leepcode-作用解析 - 5-27

    30 找不同 给定两个字符串 s 和 t,它们只包含小写字母. 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母. 请找出在 t 中被添加的字母. 示例: 输入: s = "a ...

  10. java Date类型的时间显示格式

    创建一个日期对象 使用系统的当前日期和时间创建一个日期对象并返回一个长整数的简单例子. 这个时间通常被称为Java 虚拟机(JVM)主机环境的系统时间. import java.util.Date; ...