I’m stuck!
I’m stuck!
问题描述
给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思:
'#': 任何时候玩家都不能移动到此方格;
'+': 当玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
'-': 当玩家到达这一方格后,下一步可以向左右两个方向相邻的一个非'#'方格移动一格;
'|': 当玩家到达这一方格后,下一步可以向上下两个方向相邻的一个非'#'方格移动一格;
'.': 当玩家到达这一方格后,下一步只能向下移动一格。如果下面相邻的方格为'#',则玩家不能再移动;
'S': 玩家的初始位置,地图中只会有一个初始位置。玩家到达这一方格后,下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格;
'T': 玩家的目标位置,地图中只会有一个目标位置。玩家到达这一方格后,可以选择完成任务,也可以选择不完成任务继续移动。如果继续移动下一步可以向上下左右四个方向相邻的任意一个非'#'方格移动一格。
此外,玩家不能移动出地图。
请找出满足下面两个性质的方格个数:
1. 玩家可以从初始位置移动到此方格;
2. 玩家不可以从此方格移动到目标位置。
输入格式
输入的第一行包括两个整数R 和C,分别表示地图的行和列数。(1 ≤ R, C ≤ 50)。
接下来的R行每行都包含C个字符。它们表示地图的格子。地图上恰好有一个'S'和一个'T'。
输出格式
如果玩家在初始位置就已经不能到达终点了,就输出“I'm stuck!”(不含双引号)。否则的话,输出满足性质的方格的个数。
样例输入
5 5
--+-+
..|#.
..|##
S-+-T
####.
样例输出
2
样例说明
如果把满足性质的方格在地图上用'X'标记出来的话,地图如下所示:
--+-+
..|#X
..|##
S-+-T
####X
BFS
此题是BFS的变形,原先我想从S出发,再将'.','|','-'的点全部BFS一遍,结果超时,就拿了80分。实际上BFS两次就好了,一次从S开始,一次从T开始,不过第二次要看所在点的四周能否到达这个点,能的话入队。
代码如下:
1 #include<cstdio> 2 #include<queue> 3 #include<iostream> 4 #include<cstring> 5 #include<cmath> 6 #define N 51 7 using namespace std; 8 typedef pair<int,int> P; 9 char mp[N][N]; 10 bool Smark[N][N]; 11 bool Tmark[N][N]; 12 int r,c; 13 P s,t; 14 int sum=0,psum; 15 int dx[]={-1,1,0,0}; 16 int dy[]={0,0,-1,1}; 17 void Sbfs(P start,bool Mark[][N]); 18 void Tbfs(P start,bool Mark[][N]); 19 int main(void){ 20 scanf("%d%d\n",&r,&c); 21 char temp; 22 for(int i=0;i<r;++i){ 23 for(int j=0;j<c;++j){ 24 scanf("%c",&mp[i][j]); 25 if(mp[i][j]=='S'){ 26 s.first=i; 27 s.second=j; 28 }else if(mp[i][j]=='T'){ 29 t.first=i; 30 t.second=j; 31 } 32 } 33 scanf("%c",&temp); 34 } 35 36 Sbfs(s,Smark); 37 38 if(Smark[t.first][t.second]){ 39 Tbfs(t,Tmark); 40 for(int i=0;i<r;++i){ 41 for(int j=0;j<c;++j){ 42 if(Smark[i][j]&&!Tmark[i][j]){ 43 sum++; 44 } 45 } 46 } 47 printf("%d\n",sum); 48 }else{ 49 printf("I'm stuck!\n"); 50 } 51 52 } 53 void Sbfs(P start,bool Mark[][N]){ 54 queue<P>q; 55 q.push(start); 56 while(!q.empty()){ 57 P temp=q.front(); 58 q.pop(); 59 int tx=temp.first; 60 int ty=temp.second; 61 Mark[tx][ty]=1; 62 if(mp[tx][ty]=='+'||mp[tx][ty]=='S'||mp[tx][ty]=='T'){ 63 for(int i=0;i<4;++i){ 64 int x=tx+dy[i]; 65 int y=ty+dx[i]; 66 if(0<=x&&x<r&&0<=y&&y<c&&!Mark[x][y]&&mp[x][y]!='#'){ 67 q.push(make_pair(x,y)); 68 } 69 } 70 }else if(mp[tx][ty]=='-'){ 71 for(int i=0;i<2;++i){ 72 int x=tx+dy[i]; 73 int y=ty+dx[i]; 74 if(0<=x&&x<r&&0<=y&&y<c&&!Mark[x][y]&&mp[x][y]!='#'){ 75 q.push(make_pair(x,y)); 76 } 77 } 78 }else if(mp[tx][ty]=='|'){ 79 for(int i=2;i<4;++i){ 80 int x=tx+dy[i]; 81 int y=ty+dx[i]; 82 if(0<=x&&x<r&&0<=y&&y<c&&!Mark[x][y]&&mp[x][y]!='#'){ 83 q.push(make_pair(x,y)); 84 } 85 } 86 }else if(mp[tx][ty]=='.'){ 87 int x=tx+1; 88 int y=ty; 89 if(0<=x&&x<r&&0<=y&&y<c&&!Mark[x][y]&&mp[x][y]!='#'){ 90 q.push(make_pair(x,y)); 91 } 92 } 93 } 94 } 95 void Tbfs(P start,bool Mark[][N]){ 96 queue<P>q; 97 q.push(start); 98 while(!q.empty()){ 99 P temp=q.front(); 100 q.pop(); 101 int x=temp.first; 102 int y=temp.second; 103 Mark[x][y]=1; 104 for(int i=0;i<4;++i){ 105 int sx=x+dy[i]; 106 int sy=y+dx[i]; 107 if(0<=sx&&sx<r&&0<=sy&&sy<c&&!Mark[sx][sy]){ 108 if(mp[sx][sy]=='+'||mp[sx][sy]=='S'||mp[sx][sy]=='T'){ 109 q.push(make_pair(sx,sy)); 110 }else if(mp[sx][sy]=='-'){ 111 if(sx-x==0){ 112 q.push(make_pair(sx,sy)); 113 } 114 }else if(mp[sx][sy]=='|'){ 115 if(sy-y==0){ 116 q.push(make_pair(sx,sy)); 117 } 118 }else if(mp[sx][sy]=='.'){ 119 if(sx+1==x){ 120 q.push(make_pair(sx,sy)); 121 } 122 } 123 } 124 } 125 } 126 }