poj 2312 Battle City
来源:互联网 发布:稻谷出糙率计算数据 编辑:程序博客网 时间:2024/04/30 18:37
Description
Many of us had played the game “Battle city” in our childhood, and some people (like me) even often play it on computer now. What we are discussing is a simple edition of this game. Given a map that consists of empty spaces, rivers, steel walls and brick walls only. Your task is to get a bonus as soon as possible suppose that no enemies will disturb you (See the following picture).
Your tank can’t move through rivers or walls, but it can destroy brick walls by shooting. A brick wall will be turned into empty spaces when you hit it, however, if your shot hit a steel wall, there will be no damage to the wall. In each of your turns, you can choose to move to a neighboring (4 directions, not 8) empty space, or shoot in one of the four directions without a move. The shot will go ahead in that direction, until it go out of the map or hit a wall. If the shot hits a brick wall, the wall will disappear (i.e., in this turn). Well, given the description of a map, the positions of your tank and the target, how many turns will you take at least to arrive there?
Input
The input consists of several test cases. The first line of each test case contains two integers M and N (2 <= M, N <= 300). Each of the following M lines contains N uppercase letters, each of which is one of ‘Y’ (you), ‘T’ (target), ‘S’ (steel wall), ‘B’ (brick wall), ‘R’ (river) and ‘E’ (empty space). Both ‘Y’ and ‘T’ appear only once. A test case of M = N = 0 indicates the end of input, and should not be processed.
Output
For each test case, please output the turns you take at least in a separate line. If you can’t arrive at the target, output “-1” instead.
Sample Input
3 4
YBEB
EERE
SSTE
0 0
Sample Output
8
Source
POJ Monthly, 鲁小石
声明:以下内容引自“Hackbuteer1的专栏”,对于代码有修改。(因为原来的代码与本人的代码习惯不一样,而且提交到poj上根本Accepted不了23333)
确实是一道非常好的搜索题。对于这道题,通过砖墙时和空地所花的时间不同。通过砖墙时需要耗费2个单位时间。要想用BFS就得改一下,由于BFS每次只能操作一步,要不就是扩展,要不就是破坏砖墙。所以只需检查该点是不是’B’,是的话就得停一步,不是的话,继续扩展,也就是说某些点的扩展慢了一拍,所以从队列里出来的点就判断一下再看执行哪个操作。
方法一:优先队列 + BFS
/*Problem: 2312 User: sarukaMemory: 732K Time: 47MSLanguage: G++ Result: Accepted*//* 使用STL中的优先队列 */#include<cstdio>#include<queue>#include<cstring>using namespace std;const int maxn = 305;char graph[maxn][maxn];bool vis[maxn][maxn];int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};int m, n, sx, sy;struct node{ int x, y, time; friend bool operator<(node a, node b) { return a.time > b.time; /* 切记:从小到大排序采用“>”号;如果要从大到小排序,则采用“<”号; */ }};int bfs(){ node you, start, next; priority_queue<node>q; you.x = sx; you.y = sy; you.time = 0; q.push(you); vis[sx][sy] = true; while(!q.empty()) { start=q.top(); q.pop(); for(int i = 0; i < 4; i++) { next.x = start.x + dir[i][0]; next.y = start.y + dir[i][1]; if(next.x < 0 || next.y < 0 || next.x >= m || next.y >= n || graph[next.x][next.y] == 'R' || graph[next.x][next.y] == 'S' || vis[next.x][next.y]) continue; if(graph[next.x][next.y] == 'B') next.time = start.time + 2; else next.time=start.time + 1; if(graph[next.x][next.y] == 'T') return next.time; vis[next.x][next.y] = true; q.push(next); } } return -1;}int main(){ while(scanf("%d%d", &m, &n) == 2) { if(m == 0 && n == 0) break; memset(vis, 0, sizeof(vis)); for(int i = 0; i < m; i++) { getchar(); for(int j = 0; j < n; j++) { scanf("%c", &graph[i][j]); if(graph[i][j] == 'Y') { sx = i; sy = j; } } } printf("%d\n", bfs()); } return 0;}
方法二:记忆化搜索
和优先队列BFS在出队时做处理不同的是,记忆化广搜是在点入队是做处理。记忆化广搜时不必要对点进行标记,只是在入队是注意选择。比如若搜到A点时,要选择比A点时间值大的邻接点入队(不能相等),并更新入队点的时间值。
/*Problem: 2312 User: sarukaMemory: 1104K Time: 32MSLanguage: G++ Result: Accepted*//* 记忆化搜索 */#include<cstdio>#include<cstring>#include<queue>using namespace std;const int maxn = 305;const int INF = 1009999999;int co, ro, mi;int step[maxn][maxn];char graph[maxn][maxn];bool vis[maxn][maxn];int dir[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};typedef struct node{ int x, y, time;}node;bool judge(int x, int y){ if(x < 0 || y < 0 || x >= co || y >= ro) { return false; } if(graph[x][y] == 'S'|| graph[x][y] == 'R') { return false; } return true;}void bfs(int a, int b){ int x, y, ti; node in, out; queue<node>que; in.x = a; in.y = b; step[a][b] = 0; que.push(in); while(!que.empty()) { out = que.front(); que.pop(); vis[out.x][out.y] = false; for(int i = 0; i < 4; i++) { x = out.x + dir[i][0]; y = out.y + dir[i][1]; if(!judge(x,y)) continue; ti = step[out.x][out.y] + 1; if(graph[x][y] == 'B') ti++; if(step[x][y] <= ti) continue; step[x][y] = ti; if(vis[x][y]) continue; vis[x][y] = true; in.x = x; in.y = y; que.push(in); } }}int main(){ int a, b, c, d; while(scanf("%d%d", &co, &ro) == 2 && co + ro) { getchar(); for(int i = 0; i < co; i++) gets(graph[i]); for(int i = 0; i < co; i++) { for(int j = 0; j < ro; j++) { if(graph[i][j] == 'Y') { a = i; b = j; } if(graph[i][j] == 'T') { c = i; d = j; } step[i][j] = INF; } } memset(vis, 0, sizeof(vis)); vis[a][b] = true; bfs(a, b); if(step[c][d] != INF) printf("%d\n", step[c][d]); else printf("-1\n"); } return 0;}
Powered By Saruka.
Copyright © 2016 All Rights Reserved.
- poj 2312 Battle City
- POJ 2312 Battle City
- POJ 2312 - Battle City
- poj 2312:Battle City
- POJ 2312 Battle City
- POJ 2312 Battle City
- poj 2312 Battle City
- poj 2312 Battle City
- POJ 2312 Battle City
- poj-2312-Battle City
- poj 2312 Battle City
- 【POJ 2312】Battle City
- POJ 2312 Battle City
- POJ 2312 Battle City
- Battle City(POJ 2312)
- poj 2312 Battle City-bfs
- poj 2312 Battle City bfs
- POJ 2312 Battle City 笔记
- JAVA 初学 i18n 国际化
- 第四周项目2-建设“单链表”算法库
- 撕衣服源码
- 2016 UESTC Training for Data Structures (1)
- 有关字符串的题目
- poj 2312 Battle City
- Android Context 上下文 你必须知道的一切
- python中的sum函数.sum(axis=1)
- Java学习总结第一天Java语言简介
- HTML5+javascript韩顺平坦克大战游戏教程笔记
- 关于ES、PES、PS以及TS码流
- 类的访问控制符
- 顺序表应用8:最大子段和之动态规划法
- String,StringBuffer与StringBuilder的区别