题目描述:
思路:
数据量不大,可以选择dfs或者bfs遍历两次,分别从起点和终点去遍历,看可以走到的点,分别记录在st1[][]和st2[][]中,最后找满足条件(st1[i][j]&&(!st2[i][j]))即可!
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=55;
char g[N][N];
int r,c;
bool st1[N][N],st2[N][N];
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};//上 右 下 左
bool check(int x,int y,int k)
{
if(g[x][y]=='S'||g[x][y]=='+'||g[x][y]=='T') return true;
else if(g[x][y]=='.'&&k==2) return true;
else if(g[x][y]=='-'&&(k==1||k==3)) return true;
else if(g[x][y]=='|'&&(k==0||k==2)) return true;
return false;
}
void dfs1(int a,int b)
{
//cout<<a<<" "<<b<<endl;
st1[a][b]=true;
for(int i=0;i<4;i++)
{
int x=a+dx[i];
int y=b+dy[i];
if(x<=0||x>r||y<=0||y>c||g[x][y]=='#') continue;
if(st1[x][y]) continue;
if(check(a,b,i)) dfs1(x,y);
}
}
void dfs2(int a,int b)
{
//cout<<a<<" "<<b<<endl;
st2[a][b]=true;
for(int i=0;i<4;i++)
{
int x=a+dx[i];
int y=b+dy[i];
if(x<=0||x>r||y<=0||y>c||g[x][y]=='#') continue;
if(st2[x][y]) continue;
if(check(x,y,i^2)) dfs2(x,y); //这里重点!!反向遍历呢,看下一个点是否能够能走到目前这个点
}
}
int main()
{
int sx,sy,ex,ey;
cin>>r>>c;
getchar();
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
cin>>g[i][j];
if(g[i][j]=='S') sx=i,sy=j; //初始位置坐标
if(g[i][j]=='T') ex=i,ey=j; //结束位置坐标
}
dfs1(sx,sy); //正向dfs看初始位置可以遍历到的位置
if(!st1[ex][ey]) //如果终点不能遍历到的话,那么输出并结束
{
cout<<"I'm stuck!"<<endl;
return 0;
}
dfs2(ex,ey); //从终点反向遍历,去查看能遍历到的位置
int res=0;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
{
if(st1[i][j]&&(!st2[i][j])) res++; //计数满足要求的点
}
cout<<res<<endl;
return 0;
}