地址:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1525
水神
Time Limit: 1000 MS Memory Limit: 16384 K
Total Submit: 16(5 users) Total Accepted: 6(4 users) Rating: Special Judge: No
Description
有一片被大海包围的群岛,岛上居住着一个古老的部族。很多年前部落里有一位巫师接受了水神的召唤跳入海中,从此,那一片海域就被打上了水神的烙印,被这片海域所包围的陆地也被赋予了神圣的意义(包围关系满足传递性,即海域A包围了岛B,岛B包围了海域C,而海域C中包含了岛D,则我们说海域A也包含了岛D)。
从那以后,部落里的巫师死后都必须葬在这片神圣海域所包围的岛上,而且每一个岛都只能埋葬一位巫师(否则就会被视为对水神的不敬,从而给部族带来灾难)。现在给你群岛的地图和最初那位巫师跳海的地方,请你计算一下最多可以埋葬多少巫师。
地图是一个n*m的字符矩阵,’#’代表陆地,’.’代表海洋。连通的一片陆地为一个岛,连通的一片海洋为一个海域。其中,陆地从上、下、左、右4个方向连通,海洋从上、下、左、右、左上、左下、右上、右下8个方向连通。
如下图。
图中有4个岛,2片海域。如果在A处落水,则落水的海域包围了除右上、左下两个顶角外的3个岛屿;如果在B处落水,则只包含了中间的2个岛。
Input
有多组测试数据,不超过10组。
对于每组测试数据,输入的第一行为n, m, x, y, n和m表示地图的大小(1<=n,m<=500),x和y(0 <= x < n, 0 <= y < m)是巫师跳海的地方,数据保证巫师跳海的地方是一个水域。
接下来为一个n*m的字符矩阵,共n行,每行m个字符。
Output
对于每组测试数据,输出一行,包含一个整数,为最多可以埋葬的巫师数量。
Sample Input
7 9 0 0
........#
.#######.
.#.....#.
.#.#.#.#.
.#.....#.
.#######.
#........
7 9 2 6
........#
.#######.
.#.....#.
.#.#.#.#.
.#.....#.
.#######.
#........
Sample Output
3
2
本题很难,不过或许对于你并不算难,但对于弱鸡的我还是比较难的。
下面说下思路吧,首先搜一次,把最大的水域搜出来并标记上
void bfs1(int sx,int sy)
{
queue<node>q;
node fr,ne;
fr.x=sx,fr.y=sy;
q.push(fr);
book1[sx][sy]=1;
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0; i<8; i++)
{
ne.x=fr.x+dir[i][0];
ne.y=fr.y+dir[i][1];
if(a[ne.x][ne.y]=='.'&&ne.x>=0&&ne.x<n&&ne.y>=0&&ne.y<m&&book1[ne.x][ne.y]==0)
{
book1[ne.x][ne.y]=1;
q.push(ne);
}
}
}
}
接下来从第一行,最后一行,第一列,最后一列分别进行第二次搜索,把最大水域外的区域全部搜出来。
void bfs2(int sx,int sy)
{
queue<node>q;
node fr,ne;
fr.x=sx,fr.y=sy;
q.push(fr);
book2[sx][sy]=1;
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0; i<4; i++)
{
ne.x=fr.x+dir2[i][0];
ne.y=fr.y+dir2[i][1];
if(ne.x>=0&&ne.y>=0&&ne.x<n&&ne.y<m&&book2[ne.x][ne.y]==0&&book1[ne.x][ne.y]==0)
{
book2[ne.x][ne.y]=1;
q.push(ne);
}
}
}
}
下面进行第三次搜索,第三次搜索搜的是在最大水域里面的连通块的个数。因为第二次搜索把不是最大水域里的都标记出来了,第三次搜索就非常简单了,下面是第三次搜索的代码:
void bfs3(int sx,int sy)
{
queue<node>q;
node fr,ne;
fr.x=sx,fr.y=sy;
q.push(fr);
book3[sx][sy]=1;
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0; i<4; i++)
{
ne.x=fr.x+dir2[i][0];
ne.y=fr.y+dir2[i][1];
if(ne.x>=0&&ne.x<n&&ne.y>=0&&ne.y<m&&book3[ne.x][ne.y]==0&&a[ne.x][ne.y]=='#'&&book2[ne.x][ne.y]==0)
{
book3[ne.x][ne.y]=1;
q.push(ne);
}
}
}
}
下面是完整的AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
int x,y;
};
int n,m,dir[8][2]= {{0,1},{0,-1},{1,0},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1}};
int sx,sy,book1[505][505],book2[505][505],book3[505][505],dir2[4][2]= {{0,1},{0,-1},{1,0},{-1,0}};
char a[500][500];
void bfs1(int sx,int sy)
{
queue<node>q;
node fr,ne;
fr.x=sx,fr.y=sy;
q.push(fr);
book1[sx][sy]=1;
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0; i<8; i++)
{
ne.x=fr.x+dir[i][0];
ne.y=fr.y+dir[i][1];
if(a[ne.x][ne.y]=='.'&&ne.x>=0&&ne.x<n&&ne.y>=0&&ne.y<m&&book1[ne.x][ne.y]==0)
{
book1[ne.x][ne.y]=1;
q.push(ne);
}
}
}
}
void bfs2(int sx,int sy)
{
queue<node>q;
node fr,ne;
fr.x=sx,fr.y=sy;
q.push(fr);
book2[sx][sy]=1;
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0; i<4; i++)
{
ne.x=fr.x+dir2[i][0];
ne.y=fr.y+dir2[i][1];
if(ne.x>=0&&ne.y>=0&&ne.x<n&&ne.y<m&&book2[ne.x][ne.y]==0&&book1[ne.x][ne.y]==0)
{
book2[ne.x][ne.y]=1;
q.push(ne);
}
}
}
}
void bfs3(int sx,int sy)
{
queue<node>q;
node fr,ne;
fr.x=sx,fr.y=sy;
q.push(fr);
book3[sx][sy]=1;
while(!q.empty())
{
fr=q.front();
q.pop();
for(int i=0; i<4; i++)
{
ne.x=fr.x+dir2[i][0];
ne.y=fr.y+dir2[i][1];
if(ne.x>=0&&ne.x<n&&ne.y>=0&&ne.y<m&&book3[ne.x][ne.y]==0&&a[ne.x][ne.y]=='#'&&book2[ne.x][ne.y]==0)
{
book3[ne.x][ne.y]=1;
q.push(ne);
}
}
}
}
int main()
{
while(~scanf("%d%d%d%d",&n,&m,&sx,&sy))
{
int sum=0;
for(int i=0; i<n; i++)
{
scanf("%s",&a[i]);
}
memset(book1,0,sizeof(book1));
memset(book2,0,sizeof(book2));
memset(book3,0,sizeof(book3));
bfs1(sx,sy);
for(int i=0; i<n; i++)
{
if(book1[0][i]==0)
{
bfs2(0,i);
}
}
for(int i=0; i<n; i++)
{
if(book1[n-1][i]==0)
{
bfs2(n-1,i);
}
}
for(int i=0; i<m; i++)
{
if(book1[i][0]==0)
{
bfs2(i,0);
}
}
for(int i=0; i<m; i++)
{
if(book1[i][m-1]==0)
{
bfs2(i,m-1);
}
}
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(a[i][j]=='#'&&book2[i][j]==0&&book3[i][j]==0)
{
sum++;
bfs3(i,j);
}
}
}
printf("%d\n",sum);
}
return 0;
}