[ACdream]瑶瑶带你玩激光坦克
Problem Description
有一款名为激光坦克的游戏,游戏规则是用一个坦克发出激光来达到一些目的,激光可以通过一些镜子反射。
机智的瑶瑶为了显示自己的智商高于常人,把这个游戏改造了一下,变成了用激光攻击敌人的游戏。
瑶瑶想知道射一次激光最多可以攻击到多少个敌人。
PS: 由于激光很强大,可以在击中敌人后穿过它,而瑶瑶自己的坦克由于有特殊装置,所以不会被激光击中,激光也会直接穿过它
Input
第1行两个正整数n, m (1 ≤ n, m ≤ 1000)表示地图大小,接下来n行每行m个字符描述地图。
. 表示此处为空地
* 表示此处为障碍(激光不可穿过,激光路径打到障碍时就结束)
T 代表瑶瑶的坦克位置
E 代表敌人
/ 代表按 左下-右上 放置的镜子
\ 代表按 左上-右下 放置的镜子
Output
一个整数代表瑶瑶向某个方向发射激光后最多可以攻击到的敌人数。
Sample Input
5 5 .*/E\ E*.*. E*TEE \.../ .*\EE
Sample Output
4
集体思路:
由于数据500*500=250000过大,不能用递归,否则RE,所以只能查找四个方向并标记,比较四个方向的最大值,由于有可能出现陷入死循环的可能,所以每次遇到E都要标记一下,然后下次遇到了直接跳过。这题就是判断遇到" \ "以及 ” / ".后如何判断方向的问题了,每一次查找一个就用另外一个数组标记一下,结束条件就是 遇到 “*” 的以及已经标记的,还有就是不在范围内。
AC代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include<iostream> using namespace std; #define Clear(A, X) memset (A, X, sizeof A) const int maxG = 1005; int path[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};//down, up, right, left char G[maxG][maxG]; int sr, sc, n, m; int vis[maxG][maxG][4], flag[maxG][maxG]; int stop (int nx, int ny, int way) { if (nx < 0 || nx >= n || ny < 0 || ny >= m) return 1; if (G[nx][ny] == '*') return 1; if (vis[nx][ny][way]) return 1; return 0; } int GO (int way) { Clear (vis, 0); Clear (flag, 0); int x = sr, y = sc, nx, ny, ans = 0; while (!stop (x, y, way)) { vis[x][y][way] = 1; if (G[x][y] == '\\' && way == 0) way = 2;//down -> right else if (G[x][y] == '\\' && way == 1) way = 3;//up -> left else if (G[x][y] == '\\' && way == 2) way = 0;//right -> down else if (G[x][y] == '\\' && way == 3) way = 1;//left -> up else if (G[x][y] == '/' && way == 0) way = 3;//down -> left else if (G[x][y] == '/' && way == 1) way = 2;//up -> right else if (G[x][y] == '/' && way == 2) way = 1;//right ->up else if (G[x][y] == '/' && way == 3) way = 0;//left -> down if (G[x][y] == 'E' && !flag[x][y]) ++ ans, flag[x][y] = 1; x+= path[way][0]; y+= path[way][1]; } return ans; } int main () { scanf ("%d%d", &n, &m); int ans = 0; for(int i=0; i<n; i++) scanf("%s",G[i]); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(G[i][j]=='T') { G[i][j]='.'; sr=i;sc=j; break; } } } for (int i = 0; i < 4; ++ i) ans = max (ans, GO (i)); printf ("%d\n", ans); return 0; }