Number of Islands

本文介绍了一种计算二维网格中岛屿数量的方法,通过并查集、深度优先搜索(DFS)及广度优先搜索(BFS)三种算法实现。并查集算法通过记录相连的陆地进行分类合并,而DFS和BFS则遍历整个网格标记已访问过的陆地。

思考:与Surrounded Regions类似。并查集 图算法

方法

  • 1、 利用num计数,遇到gird[i][j] = ‘1’,就让num++; 然后查看grid[i - 1][j]和grid[i - 1][j]。如果为1,则unit。在unit中,如果两个类的根不同,则num - 1;并且将两个类的根置为同一个。例如:grid[i - 1][j] == grid[i][j] == 1,则比较grid[i - 1][j]的根rootX和grid[i][j]的根rootY,如果相同则不做运算,如果不同则num - 1,并且置rootX = rootY。(数组中每个元素的根初始化为i*m+j);
  • 2、思考图算法,连通分量问题。DFS和BFS

代码

public class Solution {
    int num = 0;
    int[] unitArray;
    public int numIslands(char[][] grid) {
        if(grid.length == 0 || grid[0].length == 0)
            return 0;
        int n = grid.length;
        int m = grid[0].length;
        unitArray = new int[n * m];
        for (int i = 0; i < unitArray.length; i++)
            unitArray[i] = i;
        if(grid[0][0] == '1')
            num++;
        for(int i = 1; i < n; i++)
            if(grid[i][0] == '1'){
                num++;
                if(grid[i - 1][0] == '1')
                    unit(i * m, i * m - m);
            }
        for(int j = 1; j < m; j++)
            if(grid[0][j] == '1'){
                num++;
                if(grid[0][j - 1] == '1')
                    unit(j, j - 1);
            }
        for(int i = 1; i < n; i ++)
            for(int j = 1; j < m; j++)
                if(grid[i][j] == '1'){
                    num++;
                    if(grid[i][j] == grid[i - 1][j])
                        unit(i * m + j, i * m - m + j);
                    if(grid[i][j] == grid[i][j - 1])
                        unit(i * m + j, i * m + j - 1);
                }
        return num;
    }

    void unit(int i, int j){
        int rootI = find(i);
        int rootJ = find(j);
        if(rootI != rootJ){
            num--;
            unitArray[rootI] = rootJ;
        }
    }

    int find(int index){
        if(unitArray[index] == index) return index;
        unitArray[index] = find(unitArray[index]);
        return unitArray[index];
    }
}

DFS

class Solution {
public:
    void help(vector<vector<char>>& g, int row, int col){
       if((row < 0) || (row >= g.size()) || (col < 0) || (col >= g[row].size()) || g[row][col] != '1')
            return;
        g[row][col] = '0';
        help(g,row + 1,col);
        help(g,row - 1,col);
        help(g,row,col + 1);
        help(g,row,col - 1);
    }
    int numIslands(vector<vector<char>>& grid) {
        int answer = 0;
        for(int i  = 0; i < grid.size(); i++)
            for(int j = 0; j < grid[i].size(); j++)
                if(grid[i][j] == '1'){
                    answer++;
                    help(grid,i,j);              
                }
        return answer;
    }
};

BFS

class Solution {
public:
    void help(vector<vector<char>>& g, int x, int y){
      queue<pair<int,int>> q;
      const int dx[] = {1,-1,0,0};
      const int dy[] = {0,0,1,-1};
      g[x][y] = '0';
      for(q.push(make_pair(x,y)); !q.empty(); q.pop()){
          x = q.front().first;
          y = q.front().second;
          for(int i = 0; i < 4; i++){
              int tx = x + dx[i];
              int ty = y + dy[i];
              if((tx >= 0) && (tx < g.size()) && (ty >=0) && (ty < g[tx].size()) && g[tx][ty] == '1'){
                  q.push(make_pair(tx,ty));
                  g[tx][ty] = '0';
              }
          }
       }
    }
    int numIslands(vector<vector<char>>& grid) {
        int answer = 0;
        for(int i  = 0; i < grid.size(); i++)
            for(int j = 0; j < grid[i].size(); j++)
                if(grid[i][j] == '1'){
                    answer++;
                    help(grid,i,j);                
                }
        return answer;
    }
};
1328:Radar Installation 查看 提交 统计 提示 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d. We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates. Figure A Sample Input of Radar Installations 输入 The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases. The input is terminated by a line containing pair of zeros 输出 For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case. 生成c语言代码
最新发布
10-20
以下是用于解决雷达安装问题的 C 语言代码: ```c #include <stdio.h> #include <math.h> #include <stdlib.h> // 定义一个结构体来存储每个岛屿对应的雷达可安装区间 typedef struct { double left; double right; } Interval; // 比较函数,用于 qsort 对区间按左端点排序 int compare(const void *a, const void *b) { Interval *ia = (Interval *)a; Interval *ib = (Interval *)b; if (ia->left < ib->left) return -1; if (ia->left > ib->left) return 1; return 0; } int main() { int n, d; int case_num = 1; while (1) { scanf("%d %d", &n, &d); if (n == 0 && d == 0) break; Interval intervals[1000]; int impossible = 0; // 读取每个岛屿的坐标,并计算对应的雷达可安装区间 for (int i = 0; i < n; i++) { int x, y; scanf("%d %d", &x, &y); if (y > d) { impossible = 1; } double dx = sqrt(d * d - y * y); intervals[i].left = x - dx; intervals[i].right = x + dx; } if (impossible) { printf("Case %d: -1\n", case_num); } else { // 对区间按左端点进行排序 qsort(intervals, n, sizeof(Interval), compare); int radar_count = 1; double current_right = intervals[0].right; // 遍历排序后的区间,计算最少雷达数量 for (int i = 1; i < n; i++) { if (intervals[i].left > current_right) { radar_count++; current_right = intervals[i].right; } else if (intervals[i].right < current_right) { current_right = intervals[i].right; } } printf("Case %d: %d\n", case_num, radar_count); } case_num++; // 读取分隔用的空白行 while (getchar() != '\n'); } return 0; } ``` ### 代码解释 1. **结构体 `Interval`**:用于存储每个岛屿对应的雷达可安装区间,包含左端点 `left` 和右端点 `right`。 2. **`compare` 函数**:用于 `qsort` 对区间按左端点进行排序。 3. **主函数 `main`**: - 循环读取输入,直到遇到 `n = 0` 和 `d = 0` 时结束。 - 对于每个测试用例,读取每个岛屿的坐标,计算对应的雷达可安装区间。如果岛屿的 `y` 坐标大于雷达覆盖距离 `d`,则无法覆盖该岛屿,标记为 `impossible`。 - 如果没有无法覆盖的岛屿,对区间按左端点进行排序。 - 遍历排序后的区间,通过贪心算法计算最少雷达数量。 - 输出每个测试用例的编号和最少雷达数量,如果无法覆盖所有岛屿,则输出 `-1`。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值