CCF 201312-5 I’m stuck!
试题编号: | 201312-5 |
试题名称: | I’m stuck! |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述
给定一个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 |
关键词:dfs深度优先遍历+栈,正序建立树,倒序建立树
1 #include<iostream> 2 #include<vector> 3 #include<stack> 4 5 using namespace std; 6 bool isleft(int i,int j,vector<vector<char> > &f); 7 bool isright(int i,int j,vector<vector<char> > &f); 8 bool isup(int i,int j,vector<vector<char> > &f); 9 bool isdown(int i,int j,vector<vector<char> > &f); 10 11 void dfs(vector<vector<char> > &f,stack<pair<int,int> > &s,vector<char> &sf,int i,int j); 12 void dfs2(vector<vector<char> > &f,stack<pair<int,int> > &e,vector<char> &sf,int i,int j); 13 int r,c; 14 15 int main(){ 16 // 0 1 2 3 up down left right 17 //freopen("in2.txt","r",stdin); 18 cin >> r; 19 cin >> c; 20 int si,sj; 21 int ei,ej; 22 vector<vector<char> > f; 23 vector<char> fb; 24 for(int i = 0;i<r;i++){ 25 fb.clear(); 26 for(int j = 0;j<c;j++){ 27 char buf; 28 cin>>buf; 29 if(buf != '+' 30 && 31 buf != '-' 32 && 33 buf != '|' 34 && 35 buf != '.' 36 && 37 buf != '#' 38 && 39 buf != 'S' 40 && 41 buf != 'T'){ 42 continue; 43 } 44 if(buf == 'S'){ 45 si = i; 46 sj = j; 47 } 48 if(buf == 'T'){ 49 ei = i; 50 ej = j; 51 } 52 fb.push_back(buf); 53 } 54 f.push_back(fb); 55 } 56 vector<char> sf;//1 : 可以从起点到达的点 57 for(int i = 0;i<r*c;i++){ 58 sf.push_back(0); 59 } 60 stack<pair<int,int> > s; 61 dfs(f,s,sf,si,sj); 62 63 vector<char> ef;//1 : 可以到达终点的点 64 for(int i = 0;i<r*c;i++){ 65 ef.push_back(0); 66 } 67 stack<pair<int,int> > e; 68 dfs2(f,e,ef,ei,ej); 69 70 int suc = 0; 71 for(int i = 0;i<r;i++){ 72 for(int j = 0;j<c;j++){ 73 if(sf[c*i+j] == 1 && ef[c*i+j] == 0){ 74 suc++; 75 } 76 } 77 } 78 if(sf[c*ei+ej] == 0){ 79 cout<<"I'm stuck!"; 80 } 81 else{ 82 cout<<suc; 83 } 84 85 return 0; 86 } 87 void dfs2(vector<vector<char> > &f,stack<pair<int,int> > &e,vector<char> &ef,int i,int j){ 88 pair<int,int> m = make_pair(i,j); 89 e.push(m); 90 ef[i*c+j] = 1; 91 if(isdown(i-1,j,f)){ 92 if(ef[c*(i-1)+j] == 0){ 93 dfs2(f,e,ef,i-1,j); 94 } 95 } 96 if(isup(i+1,j,f)){ 97 if(ef[c*(i+1)+j] == 0){ 98 dfs2(f,e,ef,i+1,j); 99 } 100 } 101 if(isright(i,j-1,f)){ 102 if(ef[c*i+j-1] == 0){ 103 dfs2(f,e,ef,i,j-1); 104 } 105 } 106 if(isleft(i,j+1,f)){ 107 if(ef[c*i+j+1] == 0){ 108 dfs2(f,e,ef,i,j+1); 109 } 110 } 111 e.pop(); 112 } 113 void dfs(vector<vector<char> > &f,stack<pair<int,int> > &s,vector<char> &sf,int i,int j){ 114 pair<int,int> m = make_pair(i,j); 115 s.push(m); 116 sf[i*c+j] = 1; 117 if(isup(i,j,f)){ 118 if(sf[c*(i-1)+j] == 0){ 119 dfs(f,s,sf,i-1,j); 120 } 121 } 122 if(isdown(i,j,f)){ 123 if(sf[c*(i+1)+j] == 0){ 124 dfs(f,s,sf,i+1,j); 125 } 126 } 127 if(isleft(i,j,f)){ 128 if(sf[c*i+j-1] == 0){ 129 dfs(f,s,sf,i,j-1); 130 } 131 } 132 if(isright(i,j,f)){ 133 if(sf[c*i+j+1] == 0){ 134 dfs(f,s,sf,i,j+1); 135 } 136 } 137 s.pop(); 138 } 139 140 141 bool isup(int i,int j,vector<vector<char> > &f){ 142 if(i <= 0 143 || 144 i >= r 145 || 146 j < 0 147 || 148 j >= c 149 || 150 f[i][j] == '-' 151 || 152 f[i][j] == '.' 153 || 154 f[i][j] == '#'){ 155 return false; 156 } 157 if(f[i-1][j] == '#'){ 158 return false; 159 } 160 return true; 161 } 162 bool isdown(int i,int j,vector<vector<char> > &f){ 163 if(i >= r-1 164 || 165 i < 0 166 || 167 j < 0 168 || 169 j >= c 170 || 171 f[i][j] == '-' 172 || 173 f[i][j] == '#'){ 174 return false; 175 } 176 if(f[i+1][j] == '#'){ 177 return false; 178 } 179 return true; 180 } 181 bool isleft(int i,int j,vector<vector<char> > &f){ 182 if(j <= 0 183 || 184 j >= c 185 || 186 i < 0 187 || 188 i >= r 189 || 190 f[i][j] == '|' 191 || 192 f[i][j] == '.' 193 || 194 f[i][j] == '#'){ 195 return false; 196 } 197 if(f[i][j-1] == '#'){ 198 return false; 199 } 200 return true; 201 } 202 bool isright(int i,int j,vector<vector<char> > &f){ 203 if(j >= c-1 204 || 205 j < 0 206 || 207 i < 0 208 || 209 i >= r 210 || 211 f[i][j] == '|' 212 || 213 f[i][j] == '.' 214 || 215 f[i][j] == '#'){ 216 return false; 217 } 218 if(f[i][j+1] == '#'){ 219 return false; 220 } 221 return true; 222 }