1. 程式人生 > >NYOJ 27 水池數目 【簡單搜尋】

NYOJ 27 水池數目 【簡單搜尋】

題意:

水池數目

時間限制:3000 ms  |  記憶體限制:65535 KB 難度:4
描述
南陽理工學院校園裡有一些小河和一些湖泊,現在,我們把它們通一看成水池,假設有一張我們學校的某處的地圖,這個地圖上僅標識了此處是否是水池,現在,你的任務來了,請用計算機算出該地圖中共有幾個水池。
輸入
第一行輸入一個整數N,表示共有N組測試資料
每一組資料都是先輸入該地圖的行數m(0<m<100)與列數n(0<n<100),然後,輸入接下來的m行每行輸入n個數,表示此處有水還是沒水(1表示此處是水池,0表示此處是地面)
輸出
輸出該地圖中水池的個數。
要注意,每個水池的旁邊(上下左右四個位置)如果還是水池的話的話,它們可以看做是同一個水池。
樣例輸入
2
3 4
1 0 0 0 
0 0 1 1
1 1 1 0
5 5
1 1 1 1 0
0 0 1 0 1
0 0 0 0 0
1 1 1 0 0
0 0 1 1 1
樣例輸出
2
3
【解題思路】標記陣列,記錄訪問,如果之前被訪問,標記1,否則,訪問上下左右

詳見程式碼:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <map>
#include <set>
#include <vector>
#include <string.h>
#include <queue>
#include <stack>
using namespace std;
char s1[1001],s2[1001];
int Map[105][105]={0};
int vis[105][105]={0};                        //用於標記是否被訪問過,未訪問時為0,訪問後為1.
int dfs(int a,int b)
{
    if(vis[a][b]==1||Map[a][b]==0) return 0;  //如果訪問過,或者該點位0,結束,一定要記得返回0 
    vis[a][b]=1;                              //標記該點已經訪問了。。
    dfs(a-1,b);                               //訪問該點四周。。
    dfs(a+1,b);
    dfs(a,b-1);
    dfs(a,b+1);
    return 0;
}
int main()
{
    int n,a,b,i,j;
    cin>>n;
    while(n--)
    {
        int sum=0;                            //注意清0。。
        memset(Map,0,sizeof(Map));
        memset(vis,0,sizeof(vis));
        cin>>a>>b;
        for(i=1;i<=a;i++)
        for(j=1;j<=b;j++)
        cin>>Map[i][j];
        for(i=1;i<=a;i++)
        for(j=1;j<=b;j++)
        {
            if(Map[i][j]==0||vis[i][j]==1)    //如果該點已訪問或該點為0,直接測試下一個點。
            continue;
            else {
            sum++;
            dfs(i,j);                         //搜尋
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}