• 【伪题解】牛宫


    3.牛宫
    (long.pas/c/cpp)
    【问题描述】
    AP 神牛准备给自己盖一座很华丽的宫殿。于是,他看中了一块 N*M 的矩形空地。空
    地中每个格子都有自己的海拔高度。AP 想让他的宫殿的平均海拔在海平面之上(假设海平
    面的高度是 0,平均数都会算吧?) 。而且,AP 希望他的宫殿尽量大,能够容纳更多的人来
    膜拜他。请问 AP的宫殿最后会有多大(宫殿必须是矩形)?
    【输入】
    第一行为 N和 M。之后 N 行,每行 M 个数,描述的空地的海拔(取值范围在 longint
    范围内)。
    【输出】
    输出一行,表示宫殿最大面积。
    【输出输出样例】

    long.in

    3 2
    4 0
    -10 8
    -2 -2

    long.out
    4
    【数据规模】
    对于 30%的数据,N,M≤50;
    对于 100%的数据,N,M≤200;

    他们说要用单调栈,其实我并不知道那是啥玩意儿,不过时间放宽到2s我过完了。

    第一步 算前缀和,将这个矩阵压成一维。

    比如样例:

    4 0
    -10 8
    -2 -2

    我就存:

    4 0

    -10 -2

    -2 -4

    比如我想让矩阵纵坐标从1开始,到二结束,于是就剩下4,-2,-4,选择那一连续的一串

    使和为正且连续最长,此时可以再次使用前缀和,记录成4 2 -2,在一个一个搜1到2,1到3,2到3,

    但如果这样做会使时间很慢,于是我们知道如果1到2已经是正数,那么连续最长的是2,那么就没必要搜

    2到3了,因为即使为正,答案是一样的,如果存在4,就应该搜2到4。这样一个优化可以使时间变短。

    还有比如此时我已经搜出最大面积为4,我们还是想让纵坐标从1开始,到二结束,此时宽度为2,而它的长度

    应该超过2,就没必要搜1到2了,应该搜1到3.

    说了半天应该有人头都晕了,可以用样例试一下,帮助理解。

     1 #include <iostream>
     2 #include <fstream>
     3 #include <cstdlib>
     4 #include <iomanip>
     5 #include <cstring>
     6 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
     7 
     8 using namespace std;
     9 ifstream fin("long.in");
    10 ofstream fout("long.out");
    11 
    12 int cnt_he,cnt_zo;
    13 long long int jv_zhui[205][205]={0};
    14 long long int sum[205]={0};
    15 
    16 int xun(int z_zo,int gs,int ks){
    17  int zd=0,zd1=0;
    18  long long int qianz[205]={0};
    19  for(int x=1;x<=cnt_he;x++)qianz[x]=qianz[x-1]+jv_zhui[x][ks+gs-1]-jv_zhui[x][ks-1];    
    20  
    21  for(int x=1;x<=cnt_he;x++){
    22   long long zf=0;
    23   zd1=0;
    24   int fw=max(z_zo,zd);
    25   if(fw==0)fw=1;
    26   zf=0;
    27   for(int y=x+fw-1;y<=cnt_he;y++){
    28    zf=qianz[y]-qianz[x-1];
    29    //cout<<x<<" "<<y<<" "<<ks<<" "<<gs<<" "<<zf<<endl;
    30    //system ("pause");  
    31    if(zf>0)zd1=y-x+1;    
    32   }    
    33   zd=max(zd1,zd);    
    34  }  
    35  //cout<<zd<<" ddd "<<endl;    
    36  return zd;    
    37     
    38     
    39 }
    40 
    41 
    42 int main(int argc, char *argv[]) {
    43  fin>>cnt_he>>cnt_zo;
    44  for(int x=1;x<=cnt_he;x++){
    45   for(int y=1;y<=cnt_zo;y++){
    46    long long a=0;
    47    fin>>a;
    48    jv_zhui[x][y]=jv_zhui[x][y-1]+a;      
    49   }    
    50  }
    51  
    52  int max_mian=0;
    53  for(int x=cnt_zo;x>=1;x--){
    54   for(int y=1;y<=cnt_zo-x+1;y++){
    55    int zo=xun(max_mian/x,x,y); 
    56    
    57    max_mian=max(max_mian,x*zo);
    58    }
    59  }
    60  cout<<max_mian;
    61  fout<<max_mian;
    62  
    63  
    64  return 0;
    65 }

     QwQ,去看了一下黄学长的题解 ,然后学了学单调栈,就过完了 。

  • 相关阅读:
    Mongodb地理位置索引
    PHP中目录解析函数
    PHP中的date函数中时区问题
    PHP 文件上传全攻略
    PHP上传图片重命名6种方案
    C#|executequery要求已打开且可用的connection,连接的当前状态为已关闭
    C#|只有 assignment、call、increment、decrement 和 new 对象表达式可用作语句
    Android报错|Android Call requires API level 19 (current min is 15)
    机器学习|用机器学习预测谁将夺得世界杯冠军(附代码)
    Python|词云wordcloud入门示例
  • 原文地址:https://www.cnblogs.com/Ateisti/p/4805506.html
Copyright © 2020-2023  润新知