zoukankan      html  css  js  c++  java
  • Petrozavodsk Winter Camp, Warsaw U, 2014, A The Carpet

    一个地图上有若干障碍,问允许出现一个障碍的最大子矩形为多大?

    最大子矩形改编

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i, j, k) for (int i = int(j); i <= int(k); ++ i)
    #define dwn(i, j, k) for (int i = int(j); i >= int(k); -- i)
    const int N = 2007; 
    int n, m, l[N][2], r[N][2], h[N][2];
    char s[N][N];
    
    
    int main() {
        scanf("%d%d", &n, &m);
        rep(i, 1, n) scanf("%s", s[i] + 1);
        int ans = 0;
        // 枚举障碍不在悬线上
        // l[j][0]表示最左扩展(不能包含障碍),l[j][1]表示最右扩展(能包含障碍)
        rep(j, 1, m) l[j][0] = l[j][1] = j, r[j][0] = r[j][1] = m + 1 - j;
        rep(i, 1, n) {
            int lb0 = 0, lb1 = 0;
            rep(j, 1, m) {
                if (s[i][j] == '.') {
                    h[j][0] ++; ans = max(ans, h[j][0]);
                    l[j][1] = max(min(l[j][1], j - lb0), min(l[j][0], j - lb1));
                    l[j][0] = min(l[j][0], j - lb0);
                }
                else {
                    lb1 = lb0;
                    lb0 = j;
                    l[j][0] = l[j][1] = j;
                    h[j][0] = 0;
                }
            }
            int rb0 = m + 1, rb1 = m + 1;
            dwn(j, m, 1) {
                if (s[i][j] == '.') {
                    r[j][1] = max(min(r[j][1], rb0 - j), min(r[j][0], rb1 - j));
                    r[j][0] = min(r[j][0], rb0 - j);
                    ans = max(ans, (l[j][0] + r[j][0] - 1) * h[j][0]);
                    ans = max(ans, (l[j][0] + r[j][1] - 1) * h[j][0]);
                    ans = max(ans, (l[j][1] + r[j][0] - 1) * h[j][0]);
                }
                else {
                    rb1 = rb0;
                    rb0 = j;
                    r[j][0] = r[j][1] = m + 1 - j;
                }
            }
        }
        // 枚举障碍在悬线上
        // 这时候的l[j][0]表示没有障碍的悬线最左扩展,l[j][1]表示有障碍的悬线最左扩展
        rep(j, 1, m) l[j][0] = l[j][1] = j, r[j][0] = r[j][1] = m + 1 - j, h[j][0] = h[j][1] = 0;
        rep(i, 1, n) {
            int lb = 0;
            rep(j, 1, m) {
                if (s[i][j] == '.') {
                    h[j][0] ++; h[j][1] ++;
                    l[j][0] = min(l[j][0], j - lb);
                    l[j][1] = min(l[j][1], j - lb);
                }
                else {
                    l[j][1] = min(l[j][0], j - lb);
                    h[j][1] = h[j][0] + 1; h[j][0] = 0;
                    l[j][0] = j;
                    lb = j;
                }
            }
            int rb = m + 1;
            dwn(j, m, 1) {
                if (s[i][j] == '.') {
                    r[j][0] = min(r[j][0], rb - j);
                    r[j][1] = min(r[j][1], rb - j);
                }
                else {
                    r[j][1] = min(r[j][0], rb - j);
                    r[j][0] = m + 1 - j;
                    rb = j;
                }
            }
            rep(j, 1, m) {
                ans = max(ans, h[j][1] * (l[j][1] + r[j][1] - 1));
            }
        }   
        cout << ans << '
    ';
    }
    /*
    4 5 
    #.#.. 
    ....# 
    ..#.. 
    ....#
    */
  • 相关阅读:
    JS 实现数据分割1,123,456
    JS屏蔽键盘相关事件
    地图坐标转屏幕坐标
    对xml格式的字符串的一些操作
    ListView_Adpter
    单元测试(Android)_JUnit
    调用系统拍照
    获取手机SD卡的剩余容量(MB)
    数据库的基本操作
    临时修改模拟器手机运行内存和手机内存(不是SD卡内存)
  • 原文地址:https://www.cnblogs.com/tempestT/p/10688269.html
Copyright © 2011-2022 走看看