Problem Description
有一款名为激光坦克的游戏,游戏规则是用一个坦克发出激光来达到一些目的,激光可以通过一些镜子反射。
机智的瑶瑶为了显示自己的智商高于常人,把这个游戏改造了一下,变成了用激光攻击敌人的游戏。
瑶瑶想知道射一次激光最多可以攻击到多少个敌人。
PS: 由于激光很强大,可以在击中敌人后穿过它,而瑶瑶自己的坦克由于有特殊装置,所以不会被激光击中,激光也会直接穿过它
Input
第1行两个正整数n, m (1 ≤ n, m ≤ 1000)表示地图大小,接下来n行每行m个字符描述地图。
. 表示此处为空地
* 表示此处为障碍(激光不可穿过,激光路径打到障碍时就结束)
T 代表瑶瑶的坦克位置
E 代表敌人
/ 代表按 左下-右上 放置的镜子
\ 代表按 左上-右下 放置的镜子
Output
一个整数代表瑶瑶向某个方向发射激光后最多可以攻击到的敌人数。
Sample Input
5 5 .*/EE*.*. E*TEE \.../ .*\EE
Sample Output
4
Hint
感谢Picknight同学发现第三组数据问题!数据已更正
题意:
T为坦克的坐标,坦克向上下左右四个方向发射激光,激光能够穿过敌人E,遇到*结束,在地图的外围用*弄了的围墙,遇到/或者\发射, .表示空地,E表示敌人,问最多能够打死多少个敌人。
思路:用Map获取地图,Map_S作为标记数组,标记方式不能够赋值,而是Map_S[][]++;一个点最多经过2次,所以,判断当前的点是否已经被标记过2次,就能够判断是否死循环。还有这题的话,用递归容易RE,别问我为什么,我也不知道、、、改了好几次也还是RE、
这个是RE的代码。。。
#include <algorithm> #include <iostream> #include <stdio.h> #include <string.h> #define max(a,b)a>b?a:b #pragma comment(linker,"/STACK:102400000,102400000") using namespace std; char Map[1010][1010]; int Map_S[1010][1010]; int Begin_X,Begin_Y; int SUM; int sum; void BFS(int x,int y,int N) { if(Map[x][y]==‘*‘)return; if(Map_S[x][y]>=5)return; Map_S[x][y]++; if(Map[x][y]==‘/‘) { if(N==0)BFS(x,y-1,3); if(N==1)BFS(x,y+1,2); if(N==2)BFS(x-1,y,1); if(N==3)BFS(x+1,y,0); } if(Map[x][y]==‘\\‘) { if(N==0)BFS(x,y+1,2); if(N==1)BFS(x,y-1,3); if(N==2)BFS(x+1,y,0); if(N==3)BFS(x-1,y,1); } if(Map[x][y]==‘.‘||Map[x][y]==‘T‘||Map[x][y]==‘E‘) { if(Map[x][y]==‘E‘&&Map_S[x][y]==1)sum++; if(N==0)BFS(x+1,y,N); if(N==1)BFS(x-1,y,N); if(N==2)BFS(x,y+1,N); if(N==3)BFS(x,y-1,N); } Map_S[x][y]--; return ; } /* void Put(int N,int M) { for(int i=0;i<=N+1;i++) { for(int j=0;j<=M+1;j++) { putchar(Map[i][j]); }putchar(10); } } */ int main() { int N,M,i,j; char str; while(scanf("%d%d",&N,&M)!=EOF) { for(i=1;i<=N;i++)scanf(" %s",Map[i]+1); for(i=0;i<=N+1;i++) { for(j=0;j<=M+1;j++) { Map_S[i][j]=0; if(i==0||j==0||i==N+1||j==M+1){Map[i][j]=‘*‘;continue;} if(Map[i][j]==‘T‘) { Map[i][j]=‘.‘; Begin_X=i; Begin_Y=j; } } } /* Put(N,M);*/ SUM=0; for(i=0;i<4;i++) { sum=0; BFS(Begin_X,Begin_Y,i); SUM=max(SUM,sum); } printf("%d\n",SUM); } return 0; } /* 3 3 /EEET \E/ 3 3 /...T \./ 3 4 //E/TE/ \/E/ 3 2 /ET \/ */
这个是AC的代码。。。
1 #include <algorithm> 2 #include <iostream> 3 #include <stdio.h> 4 #include <string.h> 5 #define max(a,b)a>b?a:b 6 using namespace std; 7 char Map[1010][1010]; 8 int Map_S[1010][1010]; 9 int Work(int x,int y,int Go_To)/*x,y,为坐标,Go_To为方向*/ 10 { 11 memset(Map_S,0,sizeof(Map_S)); 12 int sum=0; 13 while(1) 14 { 15 if(Map[x][y]==‘*‘)return sum; /*如果为墙的话,就退出*/ 16 if(Map_S[x][y]>=2)return sum; /*如果该点已经经过2次了的,死循环,退出*/ 17 if(Map[x][y]==‘E‘&&Map_S[x][y]==0)sum++; /*如果该点没有被标记过,且为E,sum++*/ 18 Map_S[x][y]++; /*标记方向,需要用累加的,*/ 19 if(Map[x][y]==‘/‘) 20 { 21 switch(Go_To) 22 { 23 case 0:x=x;y=y-1;Go_To=3;break; 24 case 1:x=x;y=y+1;Go_To=2;break; 25 case 2:x=x-1;y=y;Go_To=1;break; 26 case 3:x=x+1;y=y;Go_To=0;break; 27 } 28 } 29 else if(Map[x][y]==‘\\‘) 30 { 31 switch(Go_To) 32 { 33 case 0:x=x;y=y+1;Go_To=2;break; 34 case 1:x=x;y=y-1;Go_To=3;break; 35 case 2:x=x+1;y=y;Go_To=0;break; 36 case 3:x=x-1;y=y;Go_To=1;break; 37 } 38 } 39 else if(Map[x][y]==‘.‘||Map[x][y]==‘E‘) 40 { 41 switch(Go_To) 42 { 43 case 0:x=x+1;y=y;break; 44 case 1:x=x-1;y=y;break; 45 case 2:x=x;y=y+1;break; 46 case 3:x=x;y=y-1;break; 47 } 48 } 49 } 50 return sum; 51 } 52 int main() 53 { 54 int N,M,i,j; 55 int B_X,B_Y;/*开始点*/ 56 int SUM,sum; 57 while(scanf("%d%d",&N,&M)!=EOF) 58 { 59 for(i=0;i<=N+1;i++) 60 { 61 for(j=0;j<=M+1;j++) 62 { 63 if(i==0||j==0||i==N+1||j==M+1){Map[i][j]=‘*‘;continue;} 64 scanf(" %c",&Map[i][j]); 65 if(Map[i][j]==‘T‘) /*获取起始点*/ 66 { 67 Map[i][j]=‘.‘; 68 B_X=i;B_Y=j; 69 } 70 } 71 } 72 SUM=0; 73 for(i=0;i<4;i++) 74 { 75 sum=Work(B_X,B_Y,i); 76 SUM=max(SUM,sum); 77 } 78 printf("%d\n",SUM); 79 } 80 return 0; 81 } 82 /* 83 84 3 4 85 //\E 86 /ET/ 87 \/// 88 89 3 3 90 /E 91 EET 92 \E/ 93 94 95 3 3 96 /T 97 ... 98 \./ 99 100 */