本文主要是介绍Codevs 2855 游乐园的迷宫,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
2855 游乐园的迷宫
迷宫可是每个游乐园必不可少的项目,菜菜当然是要尝试一下啦。
这个迷宫比较特殊。与其说是迷宫,倒不如说是一个巨大的格子。游乐园给菜菜发了一张地图,地图上标明了,这个格子由n行m列共n*m个小格子组成。有的格子可以正常走,标为’.’;有的格子有陷阱不能走,标为‘#’;有的格子比较特殊,标为‘*’,可以向周围八个方向可走的格子走一格;目的地标记为‘@’。菜菜从左上角处开始,并且可以按中国象棋中的马和象的方式或者特殊格的八方向来走。如果按照最短的路径到达目的地,则可以获得奖励。
菜菜当然想获得奖励啦,于是就来找你帮忙,请你帮忙计算最少需要多少步。
第一行,两个正整数n,m。
接下来的n行m列描述了地图。
一个整数,表示所要走的最小步数。若无法到达目的地则输出-1。
11 10
..........
....#.....
..........
...#.*....
.......*..
..#..#...@
*.........
...#...#..
.....*....
...#......
..*....*..
13
对于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;
}
这篇关于Codevs 2855 游乐园的迷宫的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!