HDU 1547 Bubble Shooter(BFS蔓延模擬)

Bubble Shooter

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 991 Accepted Submission(s): 419


Problem Description
Bubble shooter is a popular game. You can find a lot of versions from the Internet.



The goal of this game is to clean the bubbles off the field. Every time you just point the cannon to where you want the next bubble to go, and if three or more of bubbles with the same color came together (including the newly shot bubble), they will detonate. After the first explode, if some bubbles are disconnected from the bubble(s) in the topmost row, they will explode too.

In this problem, you will be given an arranged situation of bubbles in the field and the newly shot bubble. Your program should output the total number of bubbles that will explode.

Input
There are multiple test cases. Each test case begins with four integers H (the height of the field, 2 <= H <= 100), W (the width of the field, 2 <= W <= 100, in the picture above, W is 10), h (the vertical position of the newly shot bubble, count from top to bottom, and the topmost is counted as 1) and w (the horizontal position of the newly shot bubble, count from left to right, and the leftmost is counted as 1).
Then H lines follow, the odd lines will contain W characters while the even lines will contain W-1 characters (refer to the picture above). Each character will be either a lowercase from 'a' to 'z' indicating the color of the bubble in that position, or a capital letter 'E' indicating an empty position. You may assure the arranged situation is always valid (all the bubbles are directly or indirectly connected with at least one bubble in the topmost row, and the position of newly shot bubble is never empty).

Output
For each test case, output an integer indicating how many bubbles will explode.

Sample Input
2 2 2 1 aa a 3 3 3 3 aaa ba bba 3 3 3 1 aaa ba bba 3 3 3 3 aaa Ea aab

Sample Output
3 8 3 0

Author
JIN, Tianpeng

Source

/*
題目意思是: 給你一個H*W的矩陣,奇數行w個,偶數行w-1個字符,
E代表空,a-z代表的不同的顏色,給你一個起始座標h,w,作爲新射進去的泡泡,
如果周圍連着有三個(算上自己),則連着的一起爆炸,如果剩下的沒連着頂行
也會掉下來,問有多少掉下來 
網上註解:
題意:其實就是泡泡龍的遊戲,給你起始的地圖,以及剛打出去的泡泡的位置,
如果與剛打出的泡泡相連的泡泡數大於等於3,則相連的相同顏色的泡泡會掉下來,
之後,沒有與頂層泡泡直接或間接相連的泡泡也會掉下來。問掉下來的泡泡總數。 
*/
/*
思路:對起始泡泡進行廣搜,標記,然後枚舉頂層存在的泡泡廣搜進行染色,剩下的
和剛纔爆炸的即爲掉下來的 
注意:坑死我了!!
奇偶行的連接點並不一樣啊 看圖!!!和下面的分析!
*/
#include<iostream>
#include <string.h>
#include <queue>
using namespace std;
const int N=100+5;
char map[N][N];
bool book[N][N];
int re;
struct Node{
	int x,y;
}node,tmp;
queue<Node> q;
//方向錯了!這裏要看圖 排列的時候是交叉的
//例如偶數行時
/*
0 1 1
0 X 1
1 1 1
//奇數行時
1 1 0
1 X 1
1 1 0
*/
int step2[6][2]={{-1,0},{-1,1},{0,-1},{0,1},{1,0},{1,1}}; //odd
int step1[6][2]={{-1,-1},{-1,0},{0,-1},{0,1},{1,-1},{1,0}};
int main()
{  
    int n,m,x,y;
    while(cin>>n>>m>>x>>y){
    	re=0;
    	while(!q.empty())  q.pop();
    	memset(book,0,sizeof(book));
    	for(int i=0;i<n;i++){
    		cin>>map[i];
    		if((i+1)%2==0)
    		  map[i][m-1]='E';
		}
		/*for(int i=0;i<n;i++){
			for(int j=0;j<m;j++)
			cout<<map[i][j];
			cout<<endl;
		}*/		   
		   	x--;
		   	y--;
	    node.x=x;
	    node.y=y;
	    book[x][y]=1;
	    re++;
	    q.push(node);
	    while(!q.empty()){   //廣搜發射的起點泡泡 
	    	tmp=q.front();
	    	q.pop();
	    	for(int i=0;i<6;i++){
	    		int a,b;
	    		if((tmp.x+1)%2==1){
	    			a=tmp.x+step1[i][0];  
	    		     b=tmp.y+step1[i][1];
				}
	    	   else{
	    	     	 a=tmp.x+step2[i][0];  
	    		    b=tmp.y+step2[i][1];
			   }
	    		if(a<0||b<0||a>=n||b>=m)
	    		 continue;
			    if(book[a][b]||map[a][b]=='E')
				  continue;
				  if(map[a][b]!=map[tmp.x][tmp.y])
				   continue;
				   re++;
				  node.x=a;
				  node.y=b;
				  book[a][b]=1;
				  q.push(node);		
			}
		}
		//注意
		//注意
		//注意 
		//如果有3個或以上泡泡爆炸,則繼續,否則結束  
		//- _ -!! 這種做法是錯誤的?
		//因爲1) num<3 。
		//那麼要將之前的標記清除,
		//找出與頂層泡泡直接相連或間接相連的泡泡總數ans,
		//all-ans就是答案了。這裏解決了一個特殊情況,
	   //	本來以爲num<3的話,直接輸出0就可以了,但其實很有可能,
	   //	即使num<3,但起始的地圖也會有一些泡泡會掉下來。 
		 if(re<3)
		   {
		   	 //cout<<0<<endl;
		   	// continue;
		   	//這裏即爲發射的泡泡不會爆炸,重新將地圖初始化爲0,枚舉頂層
			   re=0;
			   memset(book,0,sizeof(book)); 
			} 
					
		//廣搜頂層泡泡  標記 			
		  for(int i=0;i<m;i++){
		 	 if(book[0][i]!=1&&map[0][i]!='E')
		 	   {
		 	      book[0][i]=1;
				   node.x=0;
				   node.y=i;
				   q.push(node);	
				   while(!q.empty()){
				   	tmp=q.front();
				   	q.pop();
				   	int a,b;
				   	for(int j=0;j<6;j++){
				   			if((tmp.x+1)%2==1){
	    	    	a=tmp.x+step1[j][0];  
	    		     b=tmp.y+step1[j][1];
				}
	    	   else{
	    	     	a=tmp.x+step2[j][0];  
	    		    b=tmp.y+step2[j][1];
			   }
				if(a>=n||a<0||b<0||b>=m)
				   			continue;				
			    if(book[a][b]||map[a][b]=='E')
				    continue;  
				    book[a][b]=1;
					node.x=a;
					node.y=b;
					q.push(node); 
					}
				   
				   }
			  }
		 } 
		 //查找剩下的
		 for(int i=0;i<n;i++){
		 	for(int j=0;j<m;j++){
		 		  if(book[i][j]==0&&map[i][j]!='E')
		 		  re++;
			 }
		 } 	
		 cout<<re<<endl;
		
	}
	return 0;
}
/*
隨便給組數據
4 5 4 4
abbbb
abbb
aabcb
aaab
答案10
*/
/*
wa了  方向要看對!! 
*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章