阿里面试题(练习)
问题描述
将一个区域,分成 m×n 个块,若某一个块有冰则用 * 表示,无冰则用 0 表示,任给一个这样的区域,
求冰田区域(冰田区域划分规则:如果两个小块之间能够在不穿越其他块的情况下连成直线,则**属于同一冰田区块)个数?
输入
4 4
* 0 0 0
0 0 0 0
0 0 * 0
0 0 0 *
4 6
0 0 0 0 0 0
0 0 * 0 0 *
0 0 * * 0 0
0 0 0 * 0 *
输出
2
3
C++实现:
#include <stdio.h> #include <iostream> #include <algorithm> #include <vector> using namespace std; /** * 总的思路是:本质就是一个floodfill算法的应用,首先需要一个和原字符表对应的标记表, * 用来标记当前元素是否已被访问,初始化为false; * 然后,从第一个元素开始遍历得到符合条件的元素,然后基于当前元素进行深度遍历即可,进行遍历的方向通过d数组来展现(本题中有八个方向); * 每次访问完一个符合要求的元素,将对应标记元素表中的标记置为true */ class Solution { private: int d[8][2] = {{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1}}; int m,n; vector< vector<bool> > visited; bool isInArea(int x,int y) { return x>=0 && x < m && y >= 0 && y < n; } void dfs(vector< vector<char> >& grid,int i,int j) { visited[i][j] = true; for (int k = 0; k < 8; ++k) { int nextX = i + d[k][0]; int nextY = j + d[k][1]; if (isInArea(nextX,nextY) && grid[nextX][nextY] == '*' && !visited[nextX][nextY]) { dfs(grid,nextX,nextY); } } return; } public: int numberOfIslands(vector< vector<char> >& grid) { m = grid.size(); if (m == 0) { return 0; } n = grid[0].size(); visited = vector< vector<bool> >(m,vector<bool>(n,false)); int islandsCount = 0; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (!visited[i][j] && grid[i][j] == '*') { islandsCount++; dfs(grid,i,j); } } } return islandsCount; } }; int main() { vector< vector<char> > input;int m,n; Solution solution; while (cin >> m >> n && m && n) { input = vector< vector<char> >(m,vector<char>(n,' ')); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { cin >> input[i][j]; } } cout << "RESULT:" << solution.numberOfIslands(input) << endl; } }
专注搬砖,擅长搬砖砸自己的脚~~~
Email:
ltwbuaa@163.com

浙公网安备 33010602011771号