1. 程式人生 > 其它 >C++-求細胞數量 解題思路

C++-求細胞數量 解題思路

題目

【Horn Studio】程式設計專欄: 求細胞數量 解題思路

題目描述

一矩形陣列由數字0到9組成。我們把數字1到9稱為細胞數字,數字0稱為非細胞數字。
若一個細胞數字上、下、左、右仍是細胞數字,我們則把這些細胞數字稱為同一細胞。 求給定矩形陣列中細胞的個數。

輸入

第1行,整數m、n(m表示行,n表示列、1<=m,n<=1001<=m,n<=100)
接下來的m行表示輸入的矩形陣列

輸出

細胞的個數

樣例輸入 複製

4  10
0234500067
1034560500
2045600671
0000000089

樣例輸出 複製

4

提示

來源

思路

經典的bfs,只需要記錄x,y。迴圈遍歷每個點,碰到1~9,而且沒有走過,ans++,從這個點開始搜尋連著的一整塊,用一個數組記錄,走過的位置和連著一塊的位置。

實質上就是一個找連通塊的問題,把整個矩陣遍歷一遍,然後把它周圍八個方塊與它相同的全部改成0,直到沒有再和它相同的為止。用搜索來做,廣搜深搜都可以。

這裡推薦使用廣搜(bfs),因為不怕超時然後TLE甚至WA,但是深搜程式碼更簡潔易懂,在dfs上只需要cv四個方向程式碼就行了。

BFS版本程式碼

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n, m, ans = 0, dx[8] = {1, -1, 0, 0}, dy[8] = {0, 0, 1, -1}, h[100013][3], zx, zy;
 4 char b[103
][103]; 5 bool a[103][103]; 6 7 void bfs(int x, int y) 8 { 9 ans++; 10 a[x][y] = false; 11 int head = 1, tail = 1; 12 h[1][1] = x, h[1][2] = y; 13 while (head <= tail) { 14 for (int i = 0; i < 4; i++) { 15 zx = h[head][1] + dx[i]; 16 zy = h[head][2
] + dy[i]; 17 if (zx >= 1 && zx <= n && zy >= 1 && zy <= m && a[zx][zy]) { 18 tail++; 19 a[zx][zy] = false; 20 h[tail][1] = zx, h[tail][2] = zy; 21 } 22 } 23 head++; 24 } 25 } 26 27 int main() 28 { 29 cin >> n >> m; 30 for (int i = 1; i <= n; i++) 31 for (int j = 1; j <= m; j++) { 32 cin >> b[i][j]; 33 if (b[i][j] != '0') 34 a[i][j] = true; 35 else 36 a[i][j] = false; 37 } 38 39 for (int i = 1; i <= n; i++) 40 for (int j = 1; j <= m; j++) 41 if (a[i][j]) 42 bfs(i, j); 43 cout << ans << endl; 44 return 0; 45 }

DFS版本程式碼(十分感謝ken_dmr提供此方面程式碼,原始碼連結:(20條訊息) 洛谷P1451 求細胞數量 用一道題理解DFS_ken_dmr的部落格-CSDN部落格

#include<stdio.h>
int m,n,ans;
int cell[105][105],book[105][105];
int dx[4]={-1,1,0,0};
int dy[4]={0,0,-1,1};
void dfs(int x,int y)
{
    book[x][y]=1;
    for(int i=0;i<4;i++)
    {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(cell[nx][ny]==0||book[nx][ny]==1) continue;
        dfs(nx,ny);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) scanf("%1d",&cell[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(book[i][j]==0&&cell[i][j]!=0)
            {
                dfs(i,j);
                ans++;
            }
        }
    printf("%d\n",ans);
    return 0;
}

彩蛋

:大家一定要有堅持的意識,最近難度可能會受打擊。(心靈雞湯)