zoukankan      html  css  js  c++  java
  • Codeforces Round #375 (Div. 2)

    题目链接:http://codeforces.com/contest/723/problem/D

    题意:给定n*m小大的字符矩阵。'*'表示陆地,'.'表示水域。然后湖的定义是:如果水域完全被陆地包围则称为湖。 海的定义:如果水域与任何一个边界的水域有连通则陈伟海。现在要求填一些湖使得最后湖的数量恰好等于K.输出最小要填多少个单位的'.'水域和最终填完之后的字符矩阵。

    思路:水题。注意本题的连通是四个方向[上下左右],然后dfs每一个连通块,对于每个连通块我们维护2个值:水域的数目和连通块属于海还是湖。 假装最终一共有x个湖。则要填(x-k)个湖。所以对于湖我们找水域最小的哪些连通块来填。

    #define _CRT_SECURE_NO_DEPRECATE
    #include<stdio.h>  
    #include<string.h>  
    #include<cstring>
    #include<algorithm>  
    #include<queue>  
    #include<math.h>  
    #include<time.h>
    #include<map>
    #include<vector>
    #include<iostream>
    using namespace std;
    typedef long long int LL;
    const int INF = 0x3f3f3f3f;
    const int MAXN = 50 + 10;
    int n, m, k, vis[MAXN][MAXN], id;
    char G[MAXN][MAXN];
    int dist[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
    struct Node{
        int cnt; //水域数目
        bool flag; //true: 海  false:湖
    }sea[MAXN*MAXN];
    bool check(int x, int y){ //是否越界
        return x >= 0 && x<n&&y >= 0 && y<m;
    }
    void dfs(int x, int y){
        int nextx, nexty;
        for (int i = 0; i<4; i++){
            nextx = x + dist[i][0];
            nexty = y + dist[i][1];
            if (check(nextx, nexty) && G[nextx][nexty] != '*'&&!vis[nextx][nexty]){
                vis[nextx][nexty] = id; sea[id].cnt++;
                if (nextx == 0 || nextx == n - 1 || nexty == 0 || nexty == m - 1){
                    sea[id].flag = true; //连通块包括边界。属于海
                }
                dfs(nextx, nexty);
            }
        }
    }
    int main(){
        while (~scanf("%d%d%d", &n, &m, &k)){
            for (int i = 0; i<n; i++){
                scanf("%s", G[i]);
            }
            memset(vis, 0, sizeof(vis)); id = 1;
            for (int i = 0; i<n; i++){
                if (i == 0 || i == n - 1){ continue; } 
                for (int j = 0; j<m; j++){
                    if (j == 0 || j == m - 1){ continue; }
                    if (G[i][j] == '.'&&!vis[i][j]){ 
                        sea[id].cnt = 1; sea[id].flag = false;
                        vis[i][j] = id; dfs(i, j); id++;
                    }
                }
            }
            int totk = 0;//统计有多少湖
            for (int i = 1; i<id; i++){
                if (sea[i].flag == false){
                    totk++;
                }
            }
            int ans = 0;  //统计要填多少单位的水域
            for (; totk>k; totk--){
                int minval = INF, minid = 0;
                for (int i = 1; i<id; i++){//枚举每一个连通块,
                    if (sea[i].flag == false){//选择湖中水域最小的湖来填
                        if (sea[i].cnt<minval){
                            minval = sea[i].cnt;  minid = i;
                        }
                    }
                }
                ans += minval; sea[minid].flag = true; //填完的湖标记一下。
                for (int i = 0; i<n; i++){
                    for (int j = 0; j<m; j++){
                        if (vis[i][j] == minid){ //找到要填的湖的连通分量
                            G[i][j] = '*';
                        }
                    }
                }
            }
            printf("%d
    ", ans);
            for (int i = 0; i<n; i++){
                printf("%s
    ", G[i]);
            }
        }
        return 0;
    }
  • 相关阅读:
    HTTP POST GET 本质区别详解< Reprinted>
    Java的反射机制
    简单的KKL诊断线~~~自己在家都可以制作obd诊断接口了 ~~
    URL-编码窗体数据无效
    没有对“C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/Temporary ASP.NET Files”的写访问权限
    ARM中的---汇编指令
    allegro中原理图和pcb中元件的交互
    运算放大器
    电流表接法
    一款单端反激开关电源的设计
  • 原文地址:https://www.cnblogs.com/kirito520/p/5930089.html
Copyright © 2011-2022 走看看