师傅又被妖怪抓走了
来源:互联网 发布:粤语教程软件 编辑:程序博客网 时间:2024/04/28 16:23
师傅又被妖怪抓走了
时间限制:1000 ms | 内存限制:65535 KB
难度:3
- 描述
话说唐僧复得了孙行者,师徒们一心同体,共诣西方。自宝象国救了公主,承君臣送出城西,沿路饥餐渴饮,悟空便为师傅去化斋,等悟空回来,悟净慌慌张张的对悟空说:“不好了,不好了”,还没等悟净说完,悟空说:“师傅又被妖怪抓走了”,悟净:“NO!” ,悟空一脸茫然,悟净:“师傅和二师兄都被妖怪抓走了”。悟空(晕!)。为了防止悟空救人,妖怪先把唐憎和八戒分别藏起来,如果悟空在T分钟之后还没找到人,那必定是被妖怪吃掉了。假设悟空在一个n行m列的矩阵内,悟空在每一分钟可以走到上,下,左,右的其中的一个可以走的位置,每次只能走一步。我们把发现定义为可以直接看到对方,也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方。
- 输入
- 有多组测试数据,每组首先是三个正整数n , m (3<=n,m<=100), T,(0<=T<=100) 分别代表行数,列数,规定的时间。接下来n 行,每行 m 个字符。其中’ S ’ 代表悟空的位置,’ D ’代表师傅位置,’ E ’代表八戒的位置。并且保证都只有一个. ’ X ’代表墙 ,’ . ’代表空地 .
- 输出
- 每组先输出一行Case c:(c表示当前的组数,从1开始计数);
接下来一行,如果悟空可以在规定时间内找到两人,则输出最少需要的时间,否则输出-1。 - 样例输入
5 6 3 XXD.......E.....X.....S. ......5 6 3 XDX... ....E. ...... ....S. ...... 5 6 8 XXDX.. .XEX.. ...... ....S. ......
- 样例输出
Case 1:-1 Case 2:3 Case 3:
-1
思路:
广搜加状态压缩, 借鉴了下大神的思路。。。
#include <stdio.h>#include <string.h>#include <queue>#include <iostream>#define MAX_SIZE 101using namespace std;typedef struct NODE{ int x, y; int step, st;}Node;char map[MAX_SIZE][MAX_SIZE]; //地图int mark[MAX_SIZE][MAX_SIZE][4], n, m, maxstep, dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};int check(int x, int y) //判断节点能不能走{ if(map[x][y] == 'D' || map[x][y] == 'E' || map[x][y] == 'X') { return 0; } else { return 1; }}char modify(char c, int flag) //给节点做初始化判断,若可以看到D返回d, 看到E返回e, 看到两个人返回y{ if((flag && c == 'd') || (!flag && c == 'e')) { return 'y'; } else { return flag ? 'e' : 'd'; }}void init(int x, int y, int flag) //将地图上D, E的四周的.初始化为y,d,e优化搜索时间{ int i; for(i = x-1; i >= 0 && check(i, y); i--) { map[i][y] = modify(map[i][y], flag); } for(i = x+1; i < n && check(i, y); i++) { map[i][y] = modify(map[i][y], flag); } for(i = y-1; i >= 0 && check(x, i); i--) { map[x][i] = modify(map[x][i], flag); } for(i = y+1; i < m && check(x, i); i++) { map[x][i] = modify(map[x][i], flag); }}int getMark(char c, int flag) //队列节点中的标记,d:01,e:10, y:11{ if(c == 'd') { flag |= 1; } else if(c == 'e') { flag |= 2; } else if(c == 'y') { flag |= 3; } return flag;}int bfs(Node sp) //普通广搜, 注意mark数组是三维的,每种状态都不同,可以来回走{ Node temp, t; sp.step = 0; sp.st = getMark(map[sp.x][sp.y], 0); memset(mark, 0, sizeof(mark)); queue<Node> q; q.push(sp); mark[sp.x][sp.y][sp.st] = 1; while(!q.empty()) { temp = q.front(); q.pop(); if(temp.st == 3) { return temp.step; } for(int i = 0; i < 4; i++) { t.x = temp.x + dir[i][0]; t.y = temp.y + dir[i][1]; t.step = temp.step + 1; if(t.x >= 0 && t.x < n && t.y >= 0 && t.y < m && check(t.x, t.y) && !mark[t.x][t.y][temp.st] && t.step <= maxstep) { t.st = getMark(map[t.x][t.y], temp.st); mark[t.x][t.y][t.st] = 1; q.push(t); } } } return -1;}int main(){ int i, j, t = 0, ans; Node sp; while(scanf("%d%d%d", &n, &m, &maxstep) != EOF) { for(i = 0; i < n; i++) { for(j = 0; j < m; j++) { cin>>map[i][j]; if(map[i][j] == 'S') { sp.x = i; sp.y = j; } } } for(i = 0; i < n; i++) //预处理地图 { for(j = 0; j < m; j++) { if(map[i][j] == 'D') { init(i, j, 0); } else if(map[i][j] == 'E') { init(i, j, 1); } } } ans = bfs(sp); //搜索 printf("Case %d:\n%d\n", ++t, ans); } return 0;}
0 0
- 师傅又被妖怪抓走了
- 师傅又被妖怪抓走了
- 师傅又被妖怪抓走了
- NYOJ999~师傅又被妖怪抓走了
- nyoj-999 师傅又被妖怪抓走了
- NYOJ 999 师傅又被妖怪抓走了(待续)
- NYOJ-999-师傅又被妖怪抓走了
- NYOJ 师傅又被妖怪抓走了 双向BFS
- nyist 999 师傅又被妖怪抓走了 【双广搜 || BFS +状态压缩】
- nyoj999 师傅又被妖怪抓走了 (预处理+bfs+状态压缩)
- 可重复广搜 —— NYOJ 999 师傅又被妖怪抓走了
- NYOJ999 师傅又被妖怪抓走了(预处理+状态压缩+广搜BFS)
- [水]Openjudge 大师兄,师傅被妖怪抓走啦
- openjudge 大师兄,师傅被妖怪抓走啦
- Openjudge6039 大师兄,师傅被妖怪抓走啦(模拟)
- 师傅,那妖怪又来了
- shu_1548 悟空的难题(大师兄,师傅被妖怪抓走啦!)
- 师傅,JAVA是妖怪!
- MAX II内部震荡时钟使用实例
- vsftp,做一个文件传输服务器和客户端程序
- iOS 7人机交互指南译文汇总
- 【Processing入门】第二章:使用Processing
- 第19章 认识与分析登录档
- 师傅又被妖怪抓走了
- 深入理解TextView实现Rich Text--在同一个TextView设置不同字体风格
- NSObject
- ALSA音频驱动研究(三)
- 谷歌最新hosts ip地址大全_谷歌google打不开的解决方法
- 彻底删除windowsxp 下的服务
- curl的简单使用
- 关于Samsung Galaxy Tabs T700 WLAN版的Root方法
- Redis源码分析(十二)——列表类型t_list