CCF-CSP-2013-12-5I’m stuck!
链接:http://118.190.20.162/view.page?gpid=T1
思路:要求计算能由S到达的点,但是不能到达T的点的数目。从S点开始dfs一下后标记,然后从T逆向遍历标记。或者从s点开始bfs遍历一遍后把访问的点加到队列中,然后计算队列中能到达T点的数目。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
char s[100][100];
int b1[100][100],b2[100][100];
int dx[]={-1,0,+1,0};
int dy[]={0,1,0,-1};
bool check(int x,int y,int k){//技巧:通过方位移动
char c=s[x][y];
if(c=='+'||c=='S'||c=='T')return true;
if(c=='-'&&(k%2))return true;
if(c=='|'&&(k%2)==0)return true;
if(c=='.'&&k==2)return true;
return false;
}
void dfs1(int x,int y){
b1[x][y]=1;
for(int i=0;i<4;i++){
int a=x+dx[i];
int b=y+dy[i];
if(b1[a][b])continue ;
if(a<1||a>n||b<1||b>m)continue ;
if(s[a][b]=='#')continue ;
if(check(x,y,i))dfs1(a,b);
}
}
void dfs2(int x,int y){
b2[x][y]=1;
for(int i=0;i<4;i++){
int a=x+dx[i];
int b=y+dy[i];
if(b2[a][b])continue;
if(a<1||b<1||a>n||b>m)continue;
if(s[a][b]=='#')continue;
if(check(a,b,i^2))dfs2(a,b);//由于是逆序检查,所以是检查(a,b)能否到达(x,y)点
}
}
int main (){
cin>>n>>m;
int x,y;
for(int i=1;i<=n;i++){
cin>>(s[i]+1);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
if(s[i][j]=='S')dfs1(i,j);
else if(s[i][j]=='T'){
x=i;
y=j;
}
}
if(!b1[x][y]){
puts("I'm stuck!");
}
else {
int ans=0;
dfs2(x,y);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(b1[i][j]&&!b2[i][j])ans++;
cout<<ans;
}
return 0;
}

浙公网安备 33010602011771号