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. (转)MyBatis框架的学习(三)——Dao层开发方法

    http://blog.csdn.net/yerenyuan_pku/article/details/71700957 使用MyBatis开发Dao层,通常有两个方法,即原始Dao开发方法和Mappe ...

  2. iterator与iterable

    用Iterator模式实现遍历集合Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内部结构.例如,如果没有使用Iterato ...

  3. MIPS——递归调用

    嵌套过程 不调用其他过程的过程称为叶过程(leaf procedure).如果所有过程都是叶过程,那么情况就很简单.但是某个过程可以调用其他过程,甚至调用的是自身的“克隆”.在调用非叶过程时使用寄存器 ...

  4. Asp.Net Core 入门(五)—— 布局视图_Layout.cshtml

    布局视图和我们在Asp.Net MVC一样,布局视图_Layout.cshtml使得所有视图保持一致的外观变得更加容易,因为我们只有一个要修改的布局视图文件,更改后将立即反映在整个应用程序的所有视图中 ...

  5. 数据库_7_SQL基本操作——表操作

    SQL基本操作——表操作 建表的过程就是声明列的过程. 表与字段是密不可分的. 一.新增数据表 create table [if not exists] 表名( 字段名字 数据类型, 字段名字 数据类 ...

  6. 什么是Java内存模型中的happens-before

    Java内存模型JMM Java内存模型(即Java Memory Model , 简称JMM),本身是一种抽象的概念,并不真实存在,它描述的是一组规则或规范,通过这组规范定义了程序个各个变量(包括实 ...

  7. 风格附加css

    #header #blogTitle { background: url("http://images.cnblogs.com/cnblogs_com/aiwuxia/1249780/o_1 ...

  8. c++ 计算彩票中奖概率

    操作方法: 输入两个数字,第一个数字是备选总数,第二个数字是选择总数,然后返回中将概率. 可以投注多次,结束的时候返回总的中将概率. #include <iostream> using n ...

  9. python3.x中的33个保留字

    Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:04:45) [MSC v.1900 32 bit (Intel)] on win32 Type " ...

  10. linux内核数据结构

    https://blog.csdn.net/zhangskd/article/details/11225301 在看ip_acct.c相关代码时看到大量使用了 hlist_nulls_for_each ...