题意:其实就是泡泡龙的游戏,给你起始的地图,以及刚打出去的泡泡的位置,如果与刚打出的泡泡相连的泡泡数大于等于3,则相连的相同颜色的泡泡会掉下来,之后,没有与顶层泡泡直接或间接相连的泡泡也会掉下来。问掉下来的泡泡总数。
分析:其实就是模拟一下就可以了。首先将与起始点直接或间接相连的相同颜色的泡泡标记一下,看总数num是否大于等于3.
all表示起始时的泡泡总数
之后要分俩种情况讨论了:
1) num<3 。那么要将之前的标记清除,找出与顶层泡泡直接相连或间接相连的泡泡总数ans,all-ans就是答案了。这里解决了一个特殊情况,本来以为num<3的话,直接输出0就可以了,但其实很有可能,即使num<3,但起始的地图也会有一些泡泡会掉下来。
2)num>=3,这种情况下,就还是找出与顶层直接相连或间接相连的泡泡总数ans,直接all-ans。这里就将俩种情况统一起来了。
#include<iostream>
#include<algorithm>
using namespace std;
char map[105][105];
bool vis[101][101];
int num,n,m,si,sj;
int dir1[6][2]={{0,1},{0,-1},{1,0},{-1,0},{-1,-1},{1,-1}};
int dir2[6][2]={{0,1},{0,-1},{1,0},{-1,0},{-1,1},{1,1}};
void dfs(int x,int y,int flag)
{
//flag表示是否要判断泡泡的颜色是否相同,因为本题目总俩次dfs的目的不同的,一个是要找出相同颜色的连通分量,一个只是要找出连通分量
if(x%2==1)
{
for(int k=0;k<6;k++)
{
int i=x+dir2[k][0];
int j=y+dir2[k][1];
if(i<0 || i>=n || j<0 || j>=m || vis[i][j] || map[i][j]=='E')
continue;
if(flag)
if(map[i][j]!=map[x][y])
continue;
vis[i][j]=1;
num++;
dfs(i,j,flag);
}
}
else {
for(int k=0;k<6;k++)
{
int i=x+dir1[k][0];
int j=y+dir1[k][1];
if(i<0 || i>=n || j<0 || j>=m || vis[i][j] || map[i][j]=='E')
continue;
if(flag)
if(map[i][j]!=map[x][y])
continue;
vis[i][j]=1;
num++;
dfs(i,j,flag);
}
}
}
int main()
{
while(scanf("%d %d %d %d",&n,&m,&si,&sj)==4)
{
int all=0;
for(int i=0;i<n;i++)
{
scanf("%s",map[i]);
if(i%2)
{
map[i][m-1]='E';
map[i][m]='\0';
}
for(int j=0;j<m;j++)
if(map[i][j]!='E')
all++;
}
memset(vis,0,sizeof(vis));
si--;sj--;
num=1;
vis[si][sj]=1;
dfs(si,sj,1);
int ans=num;
if(num<3)
{
memset(vis,0,sizeof(vis));
}
num=0;
for(int i=0;i<m;i++)
{
if(!vis[0][i] && map[0][i]!='E')
{
num++;
vis[0][i]=1;
dfs(0,i,0);
}
}
printf("%d\n",all-num);
}
return 0;
}