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 Input11 10
..........
....#.....
..........
...#.*....
.......*..
..#..#...@
*.........
...#...#..
.....*....
...#......
..*....*..
样例输出 Sample Output13
数据范围及提示 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游乐园的迷宫
版权声明:本文标题:Codevs2855游乐园的迷宫 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1732359960h1534934.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论