zoukankan      html  css  js  c++  java
  • 【思维】模拟+暴力——icpc nwrrc 2019 K

    这题思路上不是很难,但是写起来贼复杂(知道为什么没啥人过了)

    其实这题难的不是A的面积有多大,而是确定A后怎么填充剩下的矩形

    自己写的代码复制粘贴三百多行,贴上题解的得了

    题解用拉伸的填充法把代码化简了好多。。

    如果不需要最大化矩形A的面积,则可以用如下算法解决该问题。垂直拉伸每个字母,直到碰到另一个字母或王国的边界。这样,我们得到了一组完整的列。水平拉伸每一列,直到碰到另一个字母或王国的边界。

    考虑如何最大化矩形A的面积。首先,找到包含字母A且不包含其他字母的最大面积的矩形。这是一个经典问题。

    显然王国的其余部分仍可以按要求的方式分成矩形。因为我们可以将剩下的区域分为四个大矩形:矩形的A上,下,左,右侧(左上,左下,右上,右下可并到任意一个相邻的大矩形中)。

    每个大矩形都包含至少一个字母(否则我们可以在相应的方向上放大矩形A)。对于剩下的四个大矩形分别采取最开始的算法即可。

    #include <bits/stdc++.h>
    
    #define long long long int
    
    using namespace std;
    
    // @author: pashka
    
    void fill(vector<string> &a, int U, int B, int L, int R, char c) {
        for (int i = U; i < B; i++) {
            for (int j = L; j < R; j++) {
                a[i][j] = c;
            }
        }
    }
    
    char lower(char c) {
        if (c >= 'A' && c <= 'Z') {
            c = 'a' + (c - 'A');
        }
        return c;
    }
    
    void split(vector<string> &a, int U, int B, int L, int R) {
        for (int i = U + 1; i < B; i++) {
            for (int j = L; j < R; j++) {
                if (a[i][j] == '.') {
                    a[i][j] = lower(a[i - 1][j]);
                }
            }
        }
        for (int i = B - 2; i >= U; i--) {
            for (int j = L; j < R; j++) {
                if (a[i][j] == '.') {
                    a[i][j] = lower(a[i + 1][j]);
                }
            }
        }
        for (int i = U; i < B; i++) {
            for (int j = L + 1; j < R; j++) {
                if (a[i][j] == '.') {
                    a[i][j] = lower(a[i][j - 1]);
                }
            }
        }
        for (int i = U; i < B; i++) {
            for (int j = R - 2; j >= L; j--) {
                if (a[i][j] == '.') {
                    a[i][j] = lower(a[i][j + 1]);
                }
            }
        }
    }
    
    int main() {
        ios::sync_with_stdio(false);
    
        int n, m;
        cin >> n >> m;
        vector<string> a(n);
        for (int i = 0; i < n; i++) cin >> a[i];
    
        int ar = -1, ac = -1;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (a[i][j] == 'A') {
                    ar = i;
                    ac = j;
                }
            }
        }
        a[ar][ac] = '.';
    
        int maxS = -1;
        int bestL = -1;
        int bestR = -1;
        int bestU = -1;
        int bestB = -1;
        vector<int> up(m + 1);
        for (int i = 0; i < n; i++) {
            vector<pair<int, int>> s;
            for (int j = 0; j <= m; j++) {
    //            cout << i << " " << j << "
    ";
                if (j == m || a[i][j] != '.') {
                    up[j] = i + 1;
                }
                int x = j;
                while (!s.empty() && s.back().second < up[j]) {
                    int L = s.back().first;
                    int R = j;
                    int U = s.back().second;
                    int B = i + 1;
                    if (U <= ar && ar < B && L <= ac && ac < R) {
                        int S = (R - L) * (B - U);
                        if (S > maxS) {
                            maxS = S;
                            bestL = L;
                            bestR = R;
                            bestU = U;
                            bestB = B;
                        }
                    }
                    x = s.back().first;
                    s.pop_back();
                }
                s.push_back({x, up[j]});
            }
        }
    //    cout << bestU << " " << bestB << " " << bestL << " " << bestR << "
    ";
        fill(a, bestU, bestB, bestL, bestR, 'a');
    
        split(a, 0, bestU, 0, m);
        split(a, bestB, n, 0, m);
        split(a, bestU, bestB, 0, bestL);
        split(a, bestU, bestB, bestR, m);
    
        a[ar][ac] = 'A';
    
        for (int i = 0; i < n; i++) {
            cout << a[i] << "
    ";
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    喵哈哈村的魔法考试 Round #19 (Div.2) B 快速加
    hdu5676 ztr loves lucky numbers DFS
    hdu 5950 Recursive sequence 矩阵快速幂
    AI大语音(三)—傅里叶变换家族
    AI大语音(二)——语音预处理
    AI大语音(一)——语音识别基础
    第二章:声学模型之EM算法
    量子力学2
    量子力学1
    C#学习系列(一)——C#和C++的区别
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12961905.html
Copyright © 2011-2022 走看看