做题的最关键步骤是读题审题,所以让我们来看一下这一道题的题意。
提炼题意:给你一个图,要你求只与一个边(#)相连的空地(字符'.'或图以外的空间)
首先,我们易知图以外的空间只可能与一个字符‘#’相连,所以用深搜搜#时,当搜过界时ans——记录所有可能位置——加1。当搜到'.'字符时搜该字符四周,如果只有1个#字符ans++,否则无操作。搜到#字符转移位置继续搜。总之,只这三种可能,列出代码如下:
time 236 memory 204kb
#include<stdio.h> |
02 |
#include<cstring> |
03 |
using namespace std; |
04 |
05 |
const int maxn=100+10; |
06 |
char G[maxn][maxn]; |
07 |
int ans,r,c; |
08 |
bool vis[maxn][maxn]; |
09 |
10 |
int dr[]={1,-1,0,0}; |
11 |
int dc[]={0,0,1,-1}; |
12 |
13 |
void init() |
14 |
{ |
15 |
memset (G,0, sizeof (G)); |
16 |
memset (vis, false , sizeof (vis)); |
17 |
ans=0; |
18 |
} |
19 |
20 |
void dfs( int i, int j, int way) |
21 |
{ |
22 |
vis[i][j]= true ; |
23 |
if (way==1) |
24 |
{ |
25 |
int cnt=0; |
26 |
for ( int k=0;k<4;k++)
{ int x=i+dr[k]; int y=j+dc[k]; if (G[x][y]== '#' )
cnt++; } |
27 |
if (cnt==1)
ans++; |
28 |
} |
29 |
else if (way==2) |
30 |
{ |
31 |
for ( int k=0;k<4;k++) |
32 |
{ |
33 |
int x=i+dr[k]; |
34 |
int y=j+dc[k]; |
35 |
if (x<0
|| x>=r || y<0 || y>=c) ans++; |
36 |
else if (!vis[x][y]
&& G[x][y]== '.' )
dfs(x,y,1); |
37 |
else if (!vis[x][y]
&& G[x][y]== '#' )
dfs(x,y,2); |
38 |
} |
39 |
} |
40 |
} |
41 |
42 |
int main() |
43 |
{ |
44 |
int T; |
45 |
scanf ( "%d" ,&T); |
46 |
while (T--) |
47 |
{ |
48 |
scanf ( "%d
%d" ,&r,&c); |
49 |
init(); |
50 |
for ( int i=0;i<r;i++) scanf ( "%s" ,G[i]); |
51 |
for ( int i=0;i<r;i++) |
52 |
for ( int j=0;j<c;j++) |
53 |
if (!vis[i][j]
&& G[i][j]== '#' )
dfs(i,j,2); |
54 |
printf ( "%d\n" ,ans); |
55 |
} |
56 |
return 0; |
57 |
} |