CCF CSP 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 |
思路:
1.用二维数组存储这个地图,然后分别进行两次dfs;
2.分别用两个二维数组存储各个坐标是否可以从起点走到bool mvTo[55][55]
、各个坐标是否可以走到终点bool toEnd[55][55]
;
3.第一次dfs:起点从题目给的起点开始,往后dfs,每遍历到一个坐标,更新mvTo数组;第二次dfs:起点从题目给的终点开始,往前dfs,每遍历到一个坐标,更新toEnd数组;
4.注意第二次dfs的时候不是往下走,是倒着走,需要注意规则的变换;
5.最后遍历所有坐标,输出从起点可达且不可达到终点的坐标数量;
代码:
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#include<iostream>
using namespace std;
int r,c,si,sj,ti,tj;
char Map[55][55];
bool mvTo[55][55],toEnd[55][55];
bool isLegal(int i,int j){
if(i>=1&&i<=r&&j>=1&&j<=c&&Map[i][j]!='#'&&!mvTo[i][j]) return true;
else return false;
}
bool risLegal(int i,int j){
if(i>=1&&i<=r&&j>=1&&j<=c&&!toEnd[i][j]) return true;
else return false;
}
void dfs(int i,int j){
mvTo[i][j]=true;
char c=Map[i][j];
if(c=='+'||c=='|'||c=='S'||c=='T'||c=='.'){
if(c!='.'&&isLegal(i-1,j)) dfs(i-1,j);
if(isLegal(i+1,j)) dfs(i+1,j);
}
if(c=='+'||c=='-'||c=='S'||c=='T'){
if(isLegal(i,j-1)) dfs(i,j-1);
if(isLegal(i,j+1)) dfs(i,j+1);
}
}
void rdfs(int i,int j){
toEnd[i][j]=true;
char c=Map[i-1][j];
if(risLegal(i-1,j)&&(c=='+'||c=='|'||c=='S'||c=='T'||c=='.')) rdfs(i-1,j);
c=Map[i+1][j];
if(risLegal(i+1,j)&&(c=='+'||c=='|'||c=='S'||c=='T')) rdfs(i+1,j);
c=Map[i][j-1];
if(risLegal(i,j-1)&&(c=='+'||c=='-'||c=='S'||c=='T')) rdfs(i,j-1);
c=Map[i][j+1];
if(risLegal(i,j+1)&&(c=='+'||c=='-'||c=='S'||c=='T')) rdfs(i,j+1);
}
int main(){
IOS;
cin>>r>>c;
for(int i=1;i<=r;i++){
for(int j=1;j<=c;j++){
cin>>Map[i][j];
if(Map[i][j]=='S') {si=i;sj=j;}
if(Map[i][j]=='T') {ti=i;tj=j;}
}
}
dfs(si,sj);
rdfs(ti,tj);
if(!toEnd[si][sj]) cout<<"I'm stuck!";
else{
int cnt=0;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
if(mvTo[i][j]&&!toEnd[i][j]) cnt++;
cout<<cnt;
}
return 0;
}