dfs第一遍找到海,标记出来;第二遍,把海外面的部分dfs标记出来;第三遍找陆地。
第二遍dfs的起点是图的四周所有的点,这样4个方向dfs就把不被海包围的东西标记了,剩下的一定是被海包围的。
这个题比较坑的是要读好题,分清x,y是横坐标还是纵坐标。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define MAXN 510
using namespace std;
int w,h,x,y;
char map[MAXN][MAXN];
bool vis[MAXN][MAXN];
int move4[4][2]= {{0,1},{1,0},{-1,0},{0,-1}};
int move8[8][2]= {{0,1},{0,-1},{-1,0},{1,0},{1,1},{-1,1},{1,-1},{-1,-1}};
void dfssea(int a,int b)
{
if(map[a][b]=='1' ) return ;
if(map[a][b]!='.') return ;
map[a][b]='1';
for(int i=0; i<8; i++)
dfssea(a+move8[i][0],b+move8[i][1]);
}
void dfsnotsea(int a,int b,char aim)
{
if(vis[a][b]==true) return ;
if(map[a][b]=='1') return ;
if(map[a][b]=='2') return ;
map[a][b]=aim;
vis[a][b]=true;
for(int i=0; i<4; i++)
dfsnotsea(a+move4[i][0],b+move4[i][1],aim);
}
void dfs(int a,int b)
{
if(vis[a][b]||map[a][b]!='#')
return ;
vis[a][b]=true;
for(int i=0; i<4; i++)
dfs(a+move4[i][0],b+move4[i][1]);
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d%d%d",&w,&h,&x,&y);
getchar();
memset(map,'2',sizeof(map));
for(int i=1; i<=h; i++)
{
for(int j=1; j<=w; j++)
scanf("%c",&map[i][j]);
getchar();
}
memset(vis,false,sizeof(vis));
dfssea(y,x);
memset(vis,false,sizeof(vis));
for(int i=1; i<=w; i++)
dfsnotsea(1,i,'2');
for(int i=1; i<=w; i++)
dfsnotsea(h,i,'2');
for(int i=1; i<=h; i++)
dfsnotsea(i,1,'2');
for(int i=1; i<=h; i++)
dfsnotsea(i,w,'2');
memset(vis,false,sizeof(vis));
int ans=0;
for(int i=1; i<=h; i++)
{
for(int j=1; j<=w; j++)
{
if(map[i][j]=='#'&&vis[i][j]==false)
{
dfs(i,j);
ans++;
}
}
}
cout<<ans<<endl;
return 0;
}