在线笔试-城市划分-求住宅个数

来源:互联网 发布:python的注释是什么 编辑:程序博客网 时间:2024/04/28 07:32

题目要求:为了进行城市规划,需要技术安一个居民区的住宅数目。该居民区的俯视图已经制作好并划分成nxm个网格。如果某个网格具有屋顶的一部分,则向其赋值1,如果是空的,则赋值为0。由值为1的相邻网络单元组成的蔟认定为一个单独的住宅。对角放置的值为1的网格则不被视为属于同一住宅或屋顶。
函数countHome的输入包括一个二维整数数组grid及其维度n和m, 其中,n和m分别表示输入数组grid的行和列数。该函数应该返回一个表示住宅总数目的整数,网格grid只包含0和1。
输入:
[[0, 0, 0, 0, 0], [0, 1, 1, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]], 5, 5
输出:
1
输入:
[[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]], 4, 4
输出:
2
思路:
定义一个flag二维标记数组,其大小与grid大小相同,如果对应的网格已经被检查过了,将其赋1。
两个for循环,遍历grid二维数组的元素,判断该元素是否被访问过,若没有,再判断该网格是否为0, 若为零,修改flag对应的标记为已访问过。若该网格为1,进入递归函数search, search的作用是递归将网格为1的网格遍历,并将遍历过的网格对应的flag设置为一,当最终跳出该递归函数,表明该网格周围为1的网格都已经被访问过了,城市计数器自加。
代码为:

#include <iostream>#include <vector>using namespace std;void search(int **grid, bool **flag, int i, int j, int n, int m);int countHomes(int **grid, int n, int m){    if (grid == NULL)        return 0;    bool ** flag = new bool*[n];    for (int i = 0; i < n; ++i)    {        flag[i] = new bool[m];    }    // 遍历访问表    int cnt = 0;    for (int i = 0; i < n; ++i)    {        for (int j = 0; j < m; ++j)        {            flag[i][j] = 0;        }    }    for (int i = 0; i < n; ++i)    {        for (int j = 0; j < m; ++j)        {            if (flag[i][j] == 0)            {                if (grid[i][j] == 0)                {                    flag[i][j] = 1;                }                else                {                    search(grid, flag, i, j, n, m);                    cnt ++;                }            }        }    }    for (int i = 0; i < n; ++i)    {        delete []flag[i];    }    delete []flag;    return cnt;}int main(void){    cout << "n: ";    int n;    cin >> n;    cout << "m: ";    int m;    cin >> m;    int **grid = new int*[n];    for (int i = 0; i < n; ++i)    {        grid[i] = new int[m];    }    for (int i = 0; i < n; ++i)    {        for (int j = 0; j < m; ++j)        {            int temp;            cin >> temp;            grid[i][j] = temp;        }    }    cout << countHomes(grid, n, m) << endl;    for (int i = 0; i < n; ++i)    {        delete []grid[i];    }    delete []grid;    return 0;}void search(int **grid, bool **flag, int i, int j, int n, int m){    if (i >= m || j >= n)        return;    if (grid[i][j] == 1 && flag[i][j] == 0)    {        flag[i][j] = 1;        search(grid, flag, i + 1, j, m, n);        search(grid, flag, i - 1, j, m, n);        search(grid, flag, i, j + 1, m, n);        search(grid, flag, i, j - 1, m, n);    }}

多谢zhuqyh同学的指正,现将代码修改如下:在search()函数中添加了判断条件,若在范围内,则进行递归。

#include <iostream>#include <vector>using namespace std;void search(int **grid, bool **flag, int i, int j, int n, int m);int countHomes(int **grid, int n, int m);int main(void){        int n;        cout << "n: ";        cin >> n;        int m;        cout << "m: ";        cin >> m;        int **grid = new int*[n];        for (int i = 0; i < n; ++i)        {                grid[i] = new int[m];        }        for (int i = 0; i < n; ++i)        {                for (int j = 0; j < m; ++j)                {                        int temp;                        cin >> temp;                        grid[i][j] = temp;                }        }        cout << countHomes(grid, n, m) << endl;        for (int i = 0; i < n; ++i)        {                delete []grid[i];        }        delete []grid;        return 0;}int countHomes(int **grid, int n, int m){        if (grid == NULL)                return 0;        bool ** flag = new bool*[n];        for (int i = 0; i < n; ++i)        {                flag[i] = new bool[m];        }        // 遍历访问表        int cnt = 0;        for (int i = 0; i < n; ++i)        {                for (int j = 0; j < m; ++j)                {                        flag[i][j] = 0;                }        }        for (int i = 0; i < n; ++i)        {                for (int j = 0; j < m; ++j)                {                        if (flag[i][j] == 0)                        {                                if (grid[i][j] == 0)                                {                                        flag[i][j] = 1;                                }                                else                                {                                        search(grid, flag, i, j, n, m);                                        cnt ++;                                }                        }                }        }        for (int i = 0; i < n; ++i)        {                delete []flag[i];        }        delete []flag;        return cnt;}void search(int **grid, bool **flag, int i, int j, int n, int m){        if (i >= n || j >= m)                return;        if (grid[i][j] == 1 && flag[i][j] == 0)        {                flag[i][j] = 1;                // 先判断是否超过边界,若没有,再递归。                if (i + 1 >= 0 && i + 1 < n && j >= 0 && j < m)                {                    search(grid, flag, i + 1, j, m, n);                }                if (i - 1 >= 0 && i - 1 < n && j >= 0 && j < m)                {                    search(grid, flag, i - 1, j, m, n);                }                if (i >= 0 && i < n && j + 1 >= 0 && j + 1 < m)                {                    search(grid, flag, i, j + 1, m, n);                }                if (i >= 0 && i < n && j - 1 >= 0 && j - 1 < m)                {                    search(grid, flag, i, j - 1, m, n);                }        }}

若有错误之处,敬请指正。

0 0