解题思路

这是一道动态岛屿统计问题,主要思路如下:

  1. 问题分析:

    • 给定m×n的二维地图,初始全是水
    • 每次addLand操作会将一个格子变成陆地
    • 相邻的陆地(上下左右)形成一个岛屿
    • 需要统计每次操作后的岛屿数量
  2. 解决方案:

    • 使用vector存储每个岛屿的点集
    • 每次添加新点时检查是否能与现有岛屿相连
    • 如果新点能连接多个岛屿,需要合并这些岛屿
    • 维护当前岛屿的总数量
  3. 实现细节:

    • 使用Point结构体表示坐标
    • 检查新点与现有岛屿的相邻关系
    • 合并相连的岛屿
    • 处理边界情况

代码

#include <iostream>
#include <vector>
using namespace std;

struct Point {
    int x, y;
    Point(int _x, int _y) : x(_x), y(_y) {}
};

class Solution {
public:
    string countIslands(int r, int c, vector<pair<int,int>>& operations) {
        vector<vector<Point>> points;
        string res;
        int land_number = 0;
        
        for(int i = 0; i < operations.size(); i++) {
            int x = operations[i].first;
            int y = operations[i].second;
            
            if(x >= 0 && x < r && y >= 0 && y < c) {
                bool flag = true;
                int index = -1;
                Point tmp(x, y);
                
                // 检查是否能与现有岛屿相连
                for(int j = 0; j < points.size(); j++) {
                    for(int k = 0; k < points[j].size(); k++) {
                        Point& cur = points[j][k];
                        
                        if(flag) {
                            if((cur.x == x && abs(cur.y - y) <= 1) || 
                               (cur.y == y && abs(cur.x - x) <= 1)) {
                                flag = false;
                                points[j].push_back(tmp);
                                index = j;
                                break;
                            }
                        } else {
                            if((cur.x == x && abs(cur.y - y) <= 1) || 
                               (cur.y == y && abs(cur.x - x) <= 1)) {
                                // 合并岛屿
                                points[index].insert(points[index].end(), 
                                                   points[j].begin(), 
                                                   points[j].end());
                                points.erase(points.begin() + j);
                                land_number--;
                                j--;
                                break;
                            }
                        }
                    }
                }
                
                // 如果是新岛屿
                if(flag) {
                    vector<Point> tmpV;
                    tmpV.push_back(tmp);
                    points.push_back(tmpV);
                    land_number++;
                }
            }
            
            res += to_string(land_number);
            if(i < operations.size() - 1) {
                res += " ";
            }
        }
        return res;
    }
};

int main() {
    int r, c, n;
    cin >> r >> c >> n;
    
    vector<pair<int,int>> operations;
    for(int i = 0; i < n; i++) {
        int x, y;
        cin >> x >> y;
        operations.push_back({x, y});
    }
    
    Solution solution;
    cout << solution.countIslands(r, c, operations) << endl;
    return 0;
}
import java.util.*;

class Point {
    int x, y;
    Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class Main {
    public static String countIslands(int r, int c, int[][] operations) {
        List<List<Point>> points = new ArrayList<>();
        StringBuilder res = new StringBuilder();
        int landNumber = 0;
        
        for(int i = 0; i < operations.length; i++) {
            int x = operations[i][0];
            int y = operations[i][1];
            
            if(x >= 0 && x < r && y >= 0 && y < c) {
                boolean flag = true;
                int index = -1;
                Point tmp = new Point(x, y);
                
                for(int j = 0; j < points.size(); j++) {
                    List<Point> island = points.get(j);
                    for(Point cur : island) {
                        if(flag) {
                            if((cur.x == x && Math.abs(cur.y - y) <= 1) ||
                               (cur.y == y && Math.abs(cur.x - x) <= 1)) {
                                flag = false;
                                island.add(tmp);
                                index = j;
                                break;
                            }
                        } else {
                            if((cur.x == x && Math.abs(cur.y - y) <= 1) ||
                               (cur.y == y && Math.abs(cur.x - x) <= 1)) {
                                points.get(index).addAll(island);
                                points.remove(j);
                                landNumber--;
                                j--;
                                break;
                            }
                        }
                    }
                }
                
                if(flag) {
                    List<Point> newIsland = new ArrayList<>();
                    newIsland.add(tmp);
                    points.add(newIsland);
                    landNumber++;
                }
            }
            
            res.append(landNumber);
            if(i < operations.length - 1) {
                res.append(" ");
            }
        }
        return res.toString();
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int r = sc.nextInt();
        int c = sc.nextInt();
        int n = sc.nextInt();
        
        int[][] operations = new int[n][2];
        for(int i = 0; i < n; i++) {
            operations[i][0] = sc.nextInt();
            operations[i][1] = sc.nextInt();
        }
        
        System.out.println(countIslands(r, c, operations));
        sc.close();
    }
}
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def count_islands(r: int, c: int, operations: list) -> str:
    points = []  # 存储所有岛屿的点集
    result = []
    land_number = 0
    
    for x, y in operations:
        if 0 <= x < r and 0 <= y < c:
            flag = True
            index = -1
            tmp = Point(x, y)
            
            # 检查是否能与现有岛屿相连
            i = 0
            while i < len(points):
                island = points[i]
                for cur in island:
                    if flag:
                        if ((cur.x == x and abs(cur.y - y) <= 1) or 
                            (cur.y == y and abs(cur.x - x) <= 1)):
                            flag = False
                            island.append(tmp)
                            index = i
                            break
                    else:
                        if ((cur.x == x and abs(cur.y - y) <= 1) or 
                            (cur.y == y and abs(cur.x - x) <= 1)):
                            # 合并岛屿
                            points[index].extend(island)
                            points.pop(i)
                            land_number -= 1
                            i -= 1
                            break
                i += 1
            
            # 如果是新岛屿
            if flag:
                points.append([tmp])
                land_number += 1
        
        result.append(str(land_number))
    
    return ' '.join(result)

def main():
    r = int(input())
    c = int(input())
    n = int(input())
    operations = []
    for _ in range(n):
        x, y = map(int, input().split())
        operations.append((x, y))
    
    print(count_islands(r, c, operations))

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:并查集的变体
  • 时间复杂度: - 为操作次数, 为岛屿数量
  • 空间复杂度: - 为操作次数