1. 程式人生 > 其它 >【練習-6】綠紋龍的森林遊記(BFS)

【練習-6】綠紋龍的森林遊記(BFS)

技術標籤:練習冊1c++c語言bfs

綠紋龍的森林遊記

Description
暑假來了,綠紋龍很高興。於是飄飄乎就來到了森林一日遊。可是他卻看到了很不和諧的一幕,一群獵人在森林裡圍捕小動物。森林可以看做是一個10*10的方格,如下圖所示,1表示獵人,0表示小動物。
在這裡插入圖片描述

已知獵人保持不動,而小動物可以往上下左右任意方向逃脫(當然不能撞上獵人)。小動物可以逃出森林。但上圖背景色被標紅的那部分小動物將永遠無法逃脫獵人的魔爪。

Input
一個10*10的矩陣,描述森林中獵人和小動物分佈的情況。保證每個點要麼為獵人,要麼為小動物。

Output
一個整數,表示不能逃脫獵人魔爪的小動物數量。

Samples


Input
0 0 0 0 0 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0
0 0 0 0 1 0 0 1 0 0
0 0 0 0 0 1 0 0 1 0
0 0 1 0 0 0 1 0 1 0
0 1 0 1 0 1 0 0 1 0
0 1 0 0 1 1 0 1 1 0
0 0 1 0 0 0 0 1 0 0
0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 0 0 0 0 0
Output
15
Source
石光中學 FCS2018基礎班day 6

AC code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100][100];
ll ans;
void bfs(int x,int y)
{
	if(
x>=1 && x<=10 &&y>=1 &&y<=10 &&!a[x][y]) { a[x][y]=1; bfs(x+1,y); bfs(x-1,y); bfs(x,y+1); bfs(x,y-1); } return ; } int main() { for(int i=1;i<=10;i++) for(int j=1;j<=10;j++) cin>>a[i][j]; for(int i=1;i<=10;i++) { bfs(1,i); bfs
(i,1); bfs(10,i); bfs(i,10); } for(int i=1;i<=10;i++) for(int j=1;j<=10;j++) if(a[i][j]==0) ans++; cout<<ans<<endl; return 0; }

說一下大體的思路:

首先從這個二維矩陣的四個角開始bfs(1,i); bfs(i,1); bfs(10,i); bfs(i,10);向裡面掃,函式主體很容易理解:
if(x>=1 && x<=10 &&y>=1 &&y<=10 &&!a[x][y])是為了確保我們一定是在這個二維矩陣內操作,不會越界,如果遇到1就會停止。(遇到1就會停止,換言之,1起到了保護他內部0不會被修改的作用),所以可以執行的位置一定是0並且不是1內部的0.
那麼我們就把這個位置a[x][y]=1;變成1,因為他對最後的結果沒有貢獻(結果是被1包圍的0的數量)
bfs(x+1,y); bfs(x-1,y); bfs(x,y+1); bfs(x,y-1);這裡我們只需要暴力搜尋每一個可以走到的位置就可以了。

可能會有疑惑的地方是為什麼要在最開始加一個for迴圈

	for(int i=1;i<=10;i++)
	{
		bfs(1,i);
		bfs(i,1);
		bfs(10,i);
		bfs(i,10);
	}

那是因為可能會出現如下的情況(以5*5為例):

0 1 0 1 0
0 1 0 1 0
0 1 0 1 0
0 1 0 1 0
0 1 1 1 0

在這種情況下,如果只是從四個角位置上開始掃,那麼中間的4個0很顯然是掃不到的,因為他們的周圍有1的保護。
但是按照題意,這4個動物是在邊界位置的,也就是說這4個動物會逃跑,很顯然如果只是從四個角開始掃,是不符合題意的,不完整的。因此我們要在四條邊的每一個點開始掃一遍,以確保答案的正確性(沒有動物在邊界)。

完成了以上的操作,沒有被1圍起來的0(沒有被獵人包圍的動物)全都被標記成了1,而被包圍的動物很顯然,由於1的保護,仍然是0.
我們最後只要再檢驗0的數量,就可以得到最終的答案。

   for(int i=1;i<=10;i++)
        for(int j=1;j<=10;j++)
            if(a[i][j]==0)
                ans++;

以上只是鄙人的拙見,如果有錯誤、不足之處,還請指正。