Stay Hungry,Stay Foolish!

D - Grid and Magnet

D - Grid and Magnet

https://atcoder.jp/contests/abc351/tasks/abc351_d

 

思路

定义输入矩阵元素值

    s matrix each cell can have three possible values:
        0 - emtpy and not magnet field
        1 - magnet
        2 - magnet field

输入的时候,只标记 0 1

然后遍历 所有magnet cell, 将其周边 empty cell 标记为 2 - magnet field

 

以magnet fields border 将整个图 分割为若干个 连通子图, 这些连通子图元素都为 empty cells

bfs方法统计每个连通子图的 自由度 = empty cells 数目 + border cells 数目。

取最大值。

 

参考图

https://blog.csdn.net/weixin_73550568/article/details/138259299

 

 

Code

https://atcoder.jp/contests/abc351/submissions/52921148

int h, w;

int s[1005][1005];
bool v[1005][1005];

vector<pair<int, int>> dirs = {
    {0, 1},
    {0, -1},
    {1, 0},
    {-1, 0},
};

int main()
{
    cin >> h >> w;

    for(int i=0; i<h; i++){
        string oneline;
        cin >> oneline;
        
        for(int j=0; j<w; j++){
            char one = oneline[j];
            
            if (one == '#'){
                s[i][j] = 1;
            } else {
                s[i][j] = 0;
            }
        }
    }

    auto mark_magnet_fields = [&](int x, int y) -> void{
        // current position is not magnet
        if (s[x][y] != 1){
            return;
        }
        
        for(auto onedir: dirs){
            int xstep = onedir.first;
            int ystep = onedir.second;
            
            int xnew = x + xstep;
            int ynew = y + ystep;
            
            // out of grid, skip
            if (xnew < 0 || xnew >= h || ynew < 0 || ynew >= w){
                continue;
            }
            
            // only empty cell can be marked as magnet field
            // so if the neighbor cell is magnet or magnet field, skip
            if (s[xnew][ynew] != 0){
                continue;
            }
            
            s[xnew][ynew] = 2;
        }
    };

    /*
    s matrix each cell can have three possible values:
        0 - emtpy and not magnet field
        1 - magnet
        2 - magnet field
    */
    // mark magnet field
    for(int i=0; i<h; i++){
        for(int j=0; j<w; j++){
            /* current cell must be magnet */
            if (s[i][j] != 1){
                continue;
            }
            
            mark_magnet_fields(i, j);
        }
    }

    /*
    transverse all the possible connected graphs
    to get max degree
    */
    /*
    for sample 2, it tell us no empty cells exists,
    i.e. all cells can not move,
    so set default value as 1 to represent this case
    -----------
    3 3
    ..#
    #..
    ..#
    */
    int maxd = 1;
    
    auto bfs = [&](int i, int j) -> int {
        int cnt = 0;
        
        queue<pair<int, int>> qq;
        
        map<int, map<int, bool>> inqued;
        
        qq.push({i, j});
        inqued[i][j] = true;
        
        while(!qq.empty()){
            pair<int, int> front = qq.front();
            qq.pop();
            
            cnt++;
            
            int x = front.first;
            int y = front.second;
            
            // magnet field
            // other type is empty cell
            if (s[x][y] == 2){
                // DO NOTHING
                continue;
            }
            
            v[x][y] = true;

            for(auto onedir: dirs){
                int xstep = onedir.first;
                int ystep = onedir.second;

                int xnew = x + xstep;
                int ynew = y + ystep;

                // out of grid, skip
                if (xnew < 0 || xnew >= h || ynew < 0 || ynew >= w){
                    continue;
                }

                // only empty or magnet field cell can be inque
                // so if the neighbor cell is magnet, skip
                if (s[xnew][ynew] == 1){
                    continue;
                }
                
                if (inqued[xnew][ynew]){
                    continue;
                }

                qq.push({xnew, ynew});
                inqued[xnew][ynew] = true;
            }
        }
        
        return cnt;
    };
    
    for(int i=0; i<h; i++){
        for(int j=0; j<w; j++){
            /* current cell must be empty */
            if (s[i][j] != 0){
                continue;
            }
            
            // if empty cell visited, skip
            if (v[i][j]){
                continue;
            }

            int freed = bfs(i, j);
            
            maxd = max(maxd, freed);
        }
    }

    cout << maxd << endl;

    return 0;
}

 

posted @ 2024-04-28 21:57  lightsong  阅读(14)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel