hdu1547 Bubble Shooter (dfs)

题意:其实就是泡泡龙的游戏,给你起始的地图,以及刚打出去的泡泡的位置,如果与刚打出的泡泡相连的泡泡数大于等于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;
}

 

posted @ 2011-12-07 13:57  枕边梦  阅读(495)  评论(0编辑  收藏  举报