• 玉蟾宫


     题目链接:https://www.luogu.org/problemnew/show/P4147

    题目背景

    有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

    题目描述

    这片土地被分成N*M个格子,每个格子里写着'R'或者'F',R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。

    现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着'F'并且面积最大。

    但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们每人给你S两银子。

    输入输出格式

    输入格式:

    第一行两个整数N,M,表示矩形土地有N行M列。

    接下来N行,每行M个用空格隔开的字符'F'或'R',描述了矩形土地。

    输出格式:

    输出一个整数,表示你能得到多少银子,即(3*最大'F'矩形土地面积)的值。

    输入输出样例

    输入样例#1: 
    5 6 
    R F F F F F 
    F F F F F F 
    R R R F F F 
    F F F F F F 
    F F F F F F
    输出样例#1: 
    45

    说明

    对于50%的数据,1<=N,M<=200

    对于100%的数据,1<=N,M<=1000

     

     Sol one :悬线法。(详情参见王知昆dalao大佬的博客

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define LL long long
     7 #define RI register int
     8 using namespace std;
     9 const int INF = 0x7ffffff ;
    10 const int N = 1000 + 10 ;
    11 
    12 inline int read() {
    13     int k = 0 , f = 1 ; char c = getchar() ;
    14     for( ; !isdigit(c) ; c = getchar())
    15       if(c == '-') f = -1 ;
    16     for( ; isdigit(c) ; c = getchar())
    17       k = k*10 + c-'0' ;
    18     return k*f ;
    19 }
    20 int n, m ; bool hh[N][N] ; int l[N][N], r[N][N], L[N][N], R[N][N], h[N][N] ;
    21 
    22 int main() {
    23     n = read(), m = read() ;
    24     for(int i=1;i<=n;i++)
    25       for(int j=1;j<=m;j++) {
    26            char cc ; cin>>cc ;
    27            if(cc == 'F') hh[i][j] = 1 ;
    28       }
    29     for(int i=1;i<=n;i++) {
    30         int t = 0 ;
    31         for(int j=1;j<=m;j++) {
    32             if(hh[i][j]) l[i][j] = t ;
    33             else L[i][j] = 0, t = j ;
    34         }
    35         t = m+1 ;
    36         for(int j=m;j;j--) {
    37             if(hh[i][j]) r[i][j] = t ;
    38             else R[i][j] = m+1, t = j ;
    39         }
    40     }
    41     int ans = 0 ;
    42     for(int i=1;i<=m;i++) R[0][i] = m+1 ;  // 第0行一定要做好标记 
    43     for(int i=1;i<=n;i++)
    44       for(int j=1;j<=m;j++) {
    45           if(hh[i][j]) {
    46               h[i][j] = h[i-1][j]+1 ;
    47               L[i][j] = max(L[i-1][j],l[i][j]+1) ;
    48               R[i][j] = min(R[i-1][j],r[i][j]-1) ;
    49               ans = max(ans,h[i][j]*(R[i][j]-L[i][j]+1)) ;
    50           }
    51       }
    52     printf("%d",ans*3) ;
    53     return 0 ;
    54 }

      Sol two : 单调栈。枚举矩形下届,然后按照这道题:Largest Rectangle in a Histogram做就可以了。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<stack>
     7 #define LL long long
     8 #define RI register int
     9 using namespace std;
    10 const int INF = 0x7ffffff ;
    11 const int N = 1000 + 10 ;
    12 
    13 inline int read() {
    14     int k = 0 , f = 1 ; char c = getchar() ;
    15     for( ; !isdigit(c) ; c = getchar())
    16       if(c == '-') f = -1 ;
    17     for( ; isdigit(c) ; c = getchar())
    18       k = k*10 + c-'0' ;
    19     return k*f ;
    20 }
    21 int n, m, ans = 0 ; int pos[N][N], l[N] ;
    22 bool hh[N][N] ;
    23 
    24 inline void solve(int now) {
    25     stack<int>s ;
    26     for(int i=1;i<=m;i++) {
    27         while(s.size() && pos[now][s.top()] >= pos[now][i]) ans = max(ans,(i-l[s.top()]-1)*pos[now][s.top()]), s.pop() ;
    28         if(s.size()) l[i] = s.top() ; else l[i] = 0 ;  // 不初始化的话这里就要加else 
    29         s.push(i) ;
    30     }
    31     while(s.size()) ans = max(ans,(m-l[s.top()])*pos[now][s.top()]), s.pop() ;
    32 }    
    33 
    34 int main() {
    35     n = read(), m = read() ;
    36     for(int i=1;i<=n;i++) 
    37       for(int j=1;j<=m;j++) {
    38            char cc ; cin>>cc ;
    39            if(cc == 'F') hh[i][j] = 1 ;
    40       }
    41     for(int i=1;i<=n;i++)
    42       for(int j=1;j<=m;j++)
    43         if(!hh[i][j]) pos[i][j] = 0 ; else pos[i][j] = pos[i-1][j]+1 ;
    44     for(int i=1;i<=n;i++) solve(i) ;
    45     printf("%d",ans*3) ;
    46     return 0 ;
    47 }
  • 相关阅读:
    Redis学习笔记之一 : 配置redis
    Web 项目更改项目名
    Linux 常用命令之一
    SQL 常用语法一
    Java http请求和调用
    Spring c3p0连接池无法释放解决方案
    Windows和Linux查看和更改mysql连接池
    Java 简单实用方法二
    Linux 更改ssh 端口
    CentOS 通过yum安装web环境
  • 原文地址:https://www.cnblogs.com/zub23333/p/8743724.html
Copyright © 2020-2023  润新知