1. 程式人生 > >UVA-572(Oil Deposits)

UVA-572(Oil Deposits)

UVA-572(Oil Deposits)

題目:
https://cn.vjudge.net/problem/UVA-572

程式碼如下:

#include<bits/stdc++.h>
using namespace std;

char str[105][105];
bool vis[105][105];
int m,n,direction[8][2] = {{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};

void dfs(int i,int j)
{
    int dx,dy;
    for(int k = 0;k < 8;k++)//八種不同的方向
    {
        dx = i + direction[k][0];
        dy = j + direction[k][1];
        //考慮搜尋到的點是否為@,還考慮此點是否越界以及是否是新點
        if(str[dx][dy] == '@' && vis[dx][dy] && dx >= 0 && dx < m && dy >= 0 && dy < n)
        {
            vis[dx][dy] = false;
            dfs(dx,dy);
        }
    }
}

int main()
{
    int ans;
    while(scanf("%d%d",&m,&n) && m && n)
    {
        ans = 0;//每次輸入前需要將連通分量的個數初始化為0
        for(int i = 0;i < m;i++)
        {
            scanf("%s",&str[i]);
            for(int j = 0;j < n;j++) vis[i][j] = true; //初始化所有點為新點
        }
        for(int i = 0;i < m;i++)
        {
            for(int j = 0;j < n;j++)
            {
                if(str[i][j] == '@' && vis[i][j])//確保搜尋的點是@並且是新點
                {
                    ans++;//連通分量數量累加
                    dfs(i,j);
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

下來簡單介紹一下深度優先搜尋
深度優先搜尋(Depth-First-Search):
從起點出發,走過的點要做標記,發現有沒走過的點,就隨意挑一個往前走,走不了就回退,此種路徑搜尋策略就稱為“深度優先搜尋”,簡稱“深搜”。

其實稱為“遠度優先搜尋”更容易理解些。因為這種策略能往前走一步就往前走一 步,總是試圖走得更遠。所謂遠近(或深度),就是以距離起點的步數來衡量的。

題目思路:
這道題的題意簡單來說就是輸入m行n列的字元矩陣,統計字元“@”組成多少個八連塊。如果兩個字元“@”所 在的格子相鄰(橫,豎或者對角線方向),就說它們屬於同一個八連塊。

其實這道題就是要求圖中聯通分量的個數。首先定義一個二維陣列來儲存輸入的m行n列字元,然後定義一個bool型的二維陣列,並且把這些點都初始化為true(true代表的就是新點)。隨後就可以來搜尋字元為‘@’的新點。找到之後八連塊個數加1,隨行進行dfs操作。進行dfs操作時把傳入的點作為起點,起點往四處走一共有8種不同走法(橫,豎或者對角線方向)。所以使用for迴圈分別嘗試這8種不同的走法,如果走到的點是‘@’的新點那麼就進行遞迴再次執行dfs操作,並且把這個點改為false(也就是把這個點設定為舊點)。直到發現起點的周圍再無字元為‘@’的新點,然後返回main函式尋找下一個字元為‘@’的新點,每次次數加一。最後就能求出八連塊的個數。