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