题目大意:
给你一个类似于地图的东西,然后奇数行的个数比偶数行的个数多一,就跟QQ上的泡泡龙游戏一样吧,
,然后题目一开始给的你的图里面就包括了你已经射击了的那个球,并给出了这个地图的长,宽,还有起始点的坐标。你射击的泡泡中,如果有三个以上的泡泡颜色相同,那么它们就会爆炸,还有爆炸后,如果有泡泡跟从(上面往下数)第一行的泡泡没有直接或者间接相连,那么也会爆炸,求最后爆炸了多少个泡泡(题目输入中,小写字母表示泡泡的颜色,‘E’表示这个位置一开始就没有泡泡,这一点很重要啊);
解题思路:
一共要搜索两次,第一次从你射击的那个泡泡开始搜索,第二次从第一行开始搜索连通的地方,排除掉中途因为没有连接顶层而爆炸的泡泡。注意,如果第一次搜索到的相同颜色的泡泡的个数小于3,那么就要把它们标志回去visited[][]=false;最后用其实泡泡总数tal-最后搜索跟顶层相连通的泡泡数量remainder=爆炸的个数explode.
吐吐槽:
wa了很多次,因为没有注意到你射击的那个泡泡题目已经给出,还有,从顶层搜索连通的时候,忘记了有'E'这种东东存在的情况,归根结底还是题目没有看清楚。。题目没看清楚,还做个毛题啊。。为了快,最后反而变得很慢很慢。
丑陋代码:
#include
#include
const int MAX=105;
using namespace std;
typedef struct node
{
int x,y;
int num;
}N;
int h,w;
char map[MAX][MAX];
bool visited[MAX][MAX];
int dir2[6][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{0,-1}};//偶数行,右边
int dir1[6][2]={{-1,0},{0,1},{1,0},{1,-1},{0,-1},{-1,-1}};//奇数行,左边
int bfs(int x,int y,int num)//搜连通
{
queueQ;
N cur,pre;
pre.x=x,pre.y=y;
if(visited[pre.x][pre.y]==true)
return 0;
visited[pre.x][pre.y]=true;
Q.push(pre);
while(!Q.empty())
{
pre=Q.front();
Q.pop();
if(pre.x%2)//奇数行
{
for(int i=0;i<6;i++)
{
cur=pre;
cur.x+=dir1[i][0];
cur.y+=dir1[i][1];
if(cur.x>=1 && cur.x<=h && cur.y>=1 && cur.y<=w
&& visited[cur.x][cur.y]==false && map[cur.x][cur.y]!='E' && map[cur.x][cur.y]!='\0')
{
visited[cur.x][cur.y]=true;
num++;
Q.push(cur);
}
}
}
else//偶数行
{
for(int i=0;i<6;i++)
{
cur=pre;
cur.x+=dir2[i][0];
cur.y+=dir2[i][1];
if(cur.x>=1 && cur.x<=h && cur.y>=1 && cur.y<=w
&& visited[cur.x][cur.y]==false && map[cur.x][cur.y]!='E' && map[cur.x][cur.y]!='\0')
{
visited[cur.x][cur.y]=true;
num++;
Q.push(cur);
}
}
}
}
return num;
}
int bfs1(int x,int y,int num)//先搜射击的地方
{
queueQ;
N cur,pre;
pre.x=x,pre.y=y;
pre.num=1;
visited[pre.x][pre.y]=true;
Q.push(pre);
char ch=map[pre.x][pre.y];
while(!Q.empty())
{
pre=Q.front();
Q.pop();
if(pre.x%2)//奇数行
{
for(int i=0;i<6;i++)
{
cur=pre;
cur.x+=dir1[i][0];
cur.y+=dir1[i][1];
if(cur.x>=1 && cur.x<=h && cur.y>=1 && cur.y<=w
&& visited[cur.x][cur.y]==false && map[cur.x][cur.y]==ch && map[cur.x][cur.y]!='\0')
{
visited[cur.x][cur.y]=true;
num++;
Q.push(cur);
}
}
}
else//偶数行
{
for(int i=0;i<6;i++)
{
cur=pre;
cur.x+=dir2[i][0];
cur.y+=dir2[i][1];
if(cur.x>=1 && cur.x<=h && cur.y>=1 && cur.y<=w
&& visited[cur.x][cur.y]==false && map[cur.x][cur.y]==ch && map[cur.x][cur.y]!='\0')
{
visited[cur.x][cur.y]=true;
num++;
Q.push(cur);
}
}
}
}
return num;
}
void init()
{
memset(visited,false,sizeof(visited));
}
int main(void)
{
int x,y;
while(scanf("%d%d%d%d",&h,&w,&x,&y)==4)
{
int shoot_num,tal=0;
for(int i=1;i<=h;i++)
{
scanf("%s",map[i]+1);
if(i%2==0)
{
map[i][w]='E';
map[i][w+1]='\0';
}
for(int j=1;j<=w;j++)
if(map[i][j]!='E')
tal++;
}
init();
shoot_num=bfs1(x,y,1);
if(shoot_num<3)
{
memset(visited,false,sizeof(visited));//如果射击不中的,都标志为false
}
int temp=0,remainder=0;
for(int j=1;j<=w;j++)
{
if(visited[1][j]==false && map[1][j]!='E')
{
temp=bfs(1,j,1);//搜连通,即掉落的个数
remainder+=temp;
}
}
int explode=0;
explode=tal-remainder;
printf("%d\n",explode);
}
return 0;
}