1 条题解

  • 0
    @ 2025-7-20 16:52:37

    O(NM)O(NM) DFS

    需要解决两个问题:

    1. 判断整个图是否合法
    2. 计算连通块数量

    首先对于连通块的计算只要遍历数组,碰到 #dfs\texttt{dfs} 这个连通块, 然后计数即可。

    对于每个连通块来说如果合法一定是元素全为 # 的矩形,则在搜索过程中对每个连通块,都找到横、纵坐标的最小和最大值。在这个矩形范围内如果存在 . ,则必不合法。

    
    #include<bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    typedef pair<int, int> PII;
    
    #define x first
    #define y second
    
    const int N = 1e3 + 10, mod = 1e9 + 7;
    
    int n, m;
    char a[N][N];
    bool st[N][N];
    
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    
    void dfs(int x, int y, PII &minv, PII &maxv)
    {
        st[x][y] = 1;
        maxv.x = max(maxv.x, x);
        maxv.y = max(maxv.y, y);
        minv.x = min(minv.x, x);
        minv.y = min(minv.y, y);
        for(int i = 0; i < 4; i ++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if(nx < 0 || ny < 0 || nx >= n || ny >= m || st[nx][ny] || a[nx][ny] == '.') continue;
            dfs(nx, ny, minv, maxv);
        }
    }
    
    void solve()
    {
        cin >> n >> m;
        for(int i = 0; i < n; i ++)
            cin >> a[i];
            
        int ans = 0;;
        for(int i = 0; i < n; i ++)
        {
            for(int j = 0; j < m; j ++)
            {
                if(st[i][j] || a[i][j] == '.') continue;
                PII maxv = {i, j}, minv = {i, j};
                dfs(i, j, minv, maxv);
                
                // cout << minv.x << ' ' << minv.y << ' ' << maxv.x << ' ' << maxv.y <<endl;
                // check
                for(int k = minv.x; k <= maxv.x; k ++)
                    for(int l = minv.y; l <= maxv.y; l ++)
                        if(a[k][l] == '.')
                        {
                            // cout << i << ' ' << j << ' '<< k << ' ' << l << ' ' << p.x << ' ' << p.y << endl;
                            cout << "Bad placement." << endl;
                            return;
                        }
                ans ++;
            }
        }
        cout << "There are " << ans << " ships." << endl;
    }
    
    int main()
    {
        int t = 1;
        // scanf("%d", &t);
        while(t --)
            solve();
    }
    
    • 1

    信息

    ID
    158
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    13
    已通过
    5
    上传者