例題6-12 油田 圖DFS

題目:

算法競賽入門經典第二版 劉汝佳 P162例題6-12
在這裏插入圖片描述

思路:

恕臣愚鈍 這題目我一開始都沒看懂兩個八連塊怎麼數出來的。。
仔細讀了N遍。。原來就是數油田,相連的就屬於同一塊,所以這裏是兩坨油田。。
之前老師上課都講過原題哎可惜我沒聽
八連塊的八指的是以一個符號爲中心,九宮格中其他的八個,也就是遞歸遍歷的範圍

看完書自己再梳理一下思路:

  1. 遞歸: 從第一個開始遍歷符號,如果是油田 ‘ @’,則將其編號並且查詢附近的8個格子,一旦查找到有油田的,編上相同的序號並以該油田爲中心查找附近的8個格子。(實現了DFS)
  2. 標記和計數:用一個數組,初始化都存的0,第一次遇到油田即從1開始存儲(cnt),只要是相鄰的8個格子中的油田編號都相同,沒有相同的就cnt加一,說明一個油田已經查找完畢,如果再發現油田就是第二個了。最後直接輸出 cnt 就是有 “幾坨” 油田

具體的代碼實現:

  • 兩個數組,一個字符型,一個 int 型用於存儲編號cnt
  • 編號函數(遞歸函數),一旦查找到油田就將其編號,如果九宮格的其他8個格子裏還有油田就遞歸調用繼續編號。
  • 編號可以用於判斷狀態,如出界、不是油田、沒有遍歷過,idx 數組的值都會是0.如果遍歷過且是油田數組存的值就是非0
  • 字符串輸入,可以看到油田中沒有空格輸入,都是直接輸入一行的字符串存儲。(學到了。。因爲我之前不會)
 		for(int i=0; i<m; i++)
			scanf("%s",pic[i]);//字符串輸入二維數組的一行字符

代碼:

#include<cstdio>
#include<cstring>

const int maxn=100+5;
char pic[maxn][maxn];
int m,n,idx[maxn][maxn];

void dfs(int r,int c,int id)//編號函數 
{
	//對相鄰的格子進行判斷 
	if(r>=m||r<0||c>=n||c<0)return;//出界
	if(pic[r][c]!='@'||idx[r][c]>0)return;//不是油田或者已經編號過的油田 
	 
	//編號油田並且以該油田爲中心找相鄰的八個格子 
	idx[r][c]=id;
	for(int dr=-1;dr<=1;dr++)
		for(int dc=-1;dc<=1;dc++)
			if(dr!=0 || dc!=0) dfs(r+dr,c+dc,id);//遞歸實現DFS 
}
int main()
{
	while(scanf("%d%d", &m, &n)==2 && m && n)
	{
		for(int i=0;i<m;i++)
			scanf("%s",pic[i]);//通過字符串輸入 
		memset(idx, 0, sizeof(idx));//初始化 
		int cnt=0;
		for(int i=0;i<m;i++)	
			for(int j=0;j<n;j++)
				if(pic[i][j]=='@' && idx[i][j]==0) dfs(i,j,++cnt);//如果是油田且沒有編號就將其編號 
		printf("%d\n",cnt); 			
	}
	return 0;
} 


運行:

在這裏插入圖片描述

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