zoukankan      html  css  js  c++  java
  • Codevs 2855 游乐园的迷宫

              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分代码存档:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<queue>
     5 using namespace std;
     6 #define maxn 205
     7 int n,m,dis[maxn][maxn],ex,ey;
     8 int dx[]={-2,-2,-2,-2,-1,-1,+1,+1,+2,+2,+2,+2};
     9 int dy[]={-2,-1,+1,-2,+2,+2,-2,+2,-2,-1,+1,+2};
    10 int bax[]={-1,-1,-1,0,0,1,1,1};
    11 int bay[]={-1,0,1,-1,1,-1,0,1};
    12 char map[maxn][maxn];
    13 queue<int> stx,sty;
    14 bool vis[maxn][maxn];
    15 bool Judge(int xx,int yy){
    16     if(xx>0&&xx<=n&&yy>0&&yy<=m&&map[xx][yy]!='#'&&!vis[xx][yy])
    17       return true;
    18     else return false;
    19 }
    20 void BFS(){
    21     stx.push(1);sty.push(1);
    22     while(!stx.empty()){
    23         int nx=stx.front(),ny=sty.front();
    24         stx.pop();sty.pop();
    25         if(map[nx][ny]=='.'){
    26             for(int i=0;i<12;i++){
    27                 int xx=nx+dx[i],yy=ny+dy[i];
    28                 if(Judge(xx,yy)){
    29                     stx.push(xx);sty.push(yy);vis[xx][yy]=true;
    30                     dis[xx][yy]=min(dis[xx][yy],dis[nx][ny]+1);
    31                     if(xx==ex&&yy==ey) return;
    32                 }
    33             }
    34         }
    35         else if(map[nx][ny]=='*'){
    36             for(int i=0;i<8;i++){
    37                 int xx=nx+dx[i],yy=ny+dy[i];
    38                 if(Judge(xx,yy)){
    39                     stx.push(xx);sty.push(yy);vis[xx][yy]=true;
    40                     dis[xx][yy]=min(dis[xx][yy],dis[nx][ny]+1);
    41                     if(xx==ex&&yy==ey) return;
    42                 }
    43             }
    44         }
    45     }
    46 }
    47 int main()
    48 {
    49     memset(dis,0x3f,sizeof(dis));
    50     scanf("%d%d",&n,&m);
    51     for(int i=1;i<=n;i++)
    52       for(int j=1;j<=m;j++){
    53         cin>>map[i][j];
    54         if(map[i][j]=='@') ex=i,ey=j;    
    55       }
    56     dis[1][1]=0;
    57     BFS();
    58     if(dis[ex][ey]==0x3f) printf("-1
    ");
    59     else printf("%d
    ",dis[ex][ey]);
    60     return 0;
    61 }

    AC代码:

     1 #include<iostream>
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 const int maxN  = 205;
     5 char maze[maxN][maxN];
     6 int n,m;
     7 int dx,dy;
     8 bool vis[maxN][maxN];
     9 struct Node {
    10     int x,y;
    11     int dep;//记录步数
    12 };
    13 bool is_raw(int x,int y) {
    14     if(x >= 1 && x <= n && y >= 1 && y <= m && maze[x][y] != '#') return true;
    15     return false;
    16 }
    17 bool ok = false;
    18 int dir[24]= {1,2,1,-2, -1,2,-1,-2,  2,1,2,-1,  -2,-1,-2,1, //
    19               2,-2,-2,2,-2,-2,2,2};//
    20 int spec[16] = {-1,0,-1,-1,-1,1,   1,-1,1,1,1,0,  0,1,0,-1};//九宫格
    21 int ans = 0;
    22 void bfs() { //找最小,宽搜罗~
    23     Node start;
    24     start.x = 1, start.y = 1;
    25     start.dep = 0;
    26     queue<Node> q;
    27     q.push(start);
    28     while(!q.empty()) {
    29         Node head = q.front();
    30         //printf("x is %d, y is %d , dep is %d 
    ",head.x,head.y,head.dep);
    31         if(head.x == dx && head.y == dy) {
    32             ok = true;
    33             ans = head.dep;
    34             return;
    35         }
    36         q.pop();
    37         for(int i = 0 ; i < 24; i = i + 2) {
    38             if(is_raw(head.x+dir[i],head.y+dir[i+1])&&
    39                     !vis[head.x+dir[i]][head.y+dir[i+1]]) {
    40                 Node one;
    41                 vis[head.x+dir[i]][head.y+dir[i+1]] = true;
    42                 one.x = head.x+dir[i];
    43                 one.y = head.y+dir[i+1];
    44                 one.dep = head.dep+1;
    45                 q.push(one);
    46             }
    47         }
    48         if(maze[head.x][head.y] == '*') {
    49             for(int i = 0 ; i < 16; i = i + 2) {
    50                 if(is_raw(head.x+spec[i],head.y+spec[i+1])&&
    51                         !vis[head.x+spec[i]][head.y+spec[i+1]]) {
    52                     Node one;
    53                     vis[head.x+spec[i]][head.y+spec[i+1]] = true;
    54                     one.x = head.x+spec[i];
    55                     one.y = head.y+spec[i+1];
    56                     one.dep = head.dep+1;
    57                     q.push(one);
    58                 }
    59             }
    60         }
    61     }
    62 }
    63 int main() {
    64     cin>>n>>m;
    65     memset(vis,0,sizeof(vis));
    66     for(int i = 1 ; i <= n ; i++) {
    67         for(int j = 1 ; j <= m; j++) {
    68             cin>>maze[i][j];
    69             if(maze[i][j] == '@')
    70                 dx = i,dy = j;
    71         }
    72     }
    73     //printf("目标是 %d %d
    ",dx,dy);
    74     bfs();
    75     if(ok) printf("%d
    ",ans);
    76     else cout<<"-1"<<endl;
    77 }

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

    再次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
    ");
        else printf("%d
    ",dis[ex][ey]);
        return 0;
    }
    

      

  • 相关阅读:
    第一篇阅读笔记
    课程信息管理系统
    HDU1124求n的阶乘后0的个数
    分解质因数算法
    牛客小白月赛23 B阶乘(质因数分解)
    JAVAWEB将图片铺满整个页面的方法
    Codeforces Global Round 7
    POJ--1703并查集(区分两个集合)
    POJ--1611经典并查集
    DFS,BFS回顾(各种题)(肺炎疫情中,祝平安)
  • 原文地址:https://www.cnblogs.com/suishiguang/p/6284189.html
Copyright © 2011-2022 走看看