admin 管理员组

文章数量: 887006

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\n");
59     else printf("%d\n",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 \n",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\n",dx,dy);
74     bfs();
75     if(ok) printf("%d\n",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\n");else printf("%d\n",dis[ex][ey]);return 0;
}

 

  

 

本文标签: Codevs2855游乐园的迷宫