hdu1241Oil Deposits 深廣搜

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1241

題目大意:

有一個地區,用網格分成一個一個小方格,有的方格會有油田。有油田的地區用 '@' 表示,沒有的地區用 '*' 表示。當一塊油田的相鄰八個位置中有油田時,這些相鄰的油田看做一個油田。輸入這個地區的油田分佈,輸出這個地區一共有多少油田。

解題思路:

這道題是最簡單的搜索題,使用深搜廣搜都可以。最開始做這道題時,當時剛學會搜索,在高數課上用C4droid寫出來了(後來高數喜聞樂見的掛了......)。寫搜索時有幾個需要注意的地方,第一是對搜索中已訪問節點的標記,避免重複搜索導致死循環;第二是注意多維數組的下標與座標的區別,二維數組中第一個下標代表行(也就是座標中的y),第二個下標代表列(也就是座標中的x);還有就是輸入中的字符 '\n' 的處理,容易導致輸入的錯誤。

代碼:

dfs:

/*
     ID: Code-Cola
     PROG: 1241
     LANG: C++
*/

#include<iostream>
#include<cstdio>
#include<string>

using namespace std;

/********** 全局變量 **********/

int dir[8][2] = {-1,-1,0,-1,1,-1,-1,0,1,0,-1,1,0,1,1,1};        //方向數組
struct node                                                     //節點結構體
{
    int x,y;
};
string s[110];
int n,m;

/********** 函數聲明 **********/

bool IsOk(int x, int y);                                        //判斷是否訪問越界
void dfs(int x, int y);                                         //深搜

int main()
{
    int i,j,sum;
    while (cin >> m >> n && m && n) {
        getchar();                                              //'\n'
        for (i = 0; i < m; i++)
            getline(cin,s[i]);
        for (i = 0, sum = 0; i < m; i++)
            for (j = 0; j < n; j++)
                if (s[i][j] == '@') {
                    dfs(j,i);
                    sum++;                                      //記錄油田數目
                }
        cout << sum << endl;
    }
    return 0;
}

bool IsOk(int x,int y)
{
    return x >= 0 && x < n ? y >= 0 && y < m ? true : false : false;
}

void dfs(int x, int y)
{
    node t;
    s[y][x] = '*';                                               //標記
    for (int i = 0; i < 8; i++){
        t.x = x + dir[i][0];
        t.y = y + dir[i][1];
        if (IsOk(t.x, t.y) && s[t.y][t.x] == '@')                //判斷是否滿足搜索條件
            dfs(t.x, t.y);
    }
}

bfs:

/*
     ID: Code-Cola
     PROG: 1241
     LANG: C++
*/

#include<iostream>
#include<cstdio>
#include<string>
#include<queue>

using namespace std;

/********** 全局變量 **********/

int dir[8][2] = {-1,-1,0,-1,1,-1,-1,0,1,0,-1,1,0,1,1,1};        //方向數組
struct node                                                     //節點結構體
{
    int x,y;
};
string s[110];
int n,m;
queue<node> q;

/********** 函數聲明 **********/

bool IsOk(int x, int y);                                        //判斷是否訪問越界
void bfs(int x, int y);                                         //廣搜

int main()
{
    int i,j,sum;
    while (cin >> m >> n && m && n) {
        getchar();                                              //'\n'
        for (i = 0; i < m; i++)
            getline(cin,s[i]);
        for (i = 0, sum = 0; i < m; i++)
            for (j = 0; j < n; j++)
                if (s[i][j] == '@') {
                    bfs(j,i);
                    sum++;                                      //記錄油田數目
                }
        cout << sum << endl;
    }
    return 0;
}

bool IsOk(int x,int y)
{
    return x >= 0 && x < n ? y >= 0 && y < m ? true : false : false;
}

void bfs(int x, int y)
{
    node t,temp;
    while (!q.empty()) {                                        //清空隊列 PS:貌似沒必要
        q.pop();
    }
    t.x = x, t.y = y;
    q.push(t);
    s[y][x] = '*';
    while (!q.empty()) {
        t.x = q.front().x;
        t.y = q.front().y;
        q.pop();
        for (int i = 0; i < 8; i++) {                           //8個方向搜索
            temp.x = t.x + dir[i][0];
            temp.y = t.y + dir[i][1];
            if (IsOk(temp.x, temp.y) && s[temp.y][temp.x] == '@') {
                s[temp.y][temp.x] = '*';                        //一定要進入隊列前標記不可走
                q.push(temp);
            }
        }
    }
}


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