• COJ 2105 submatrix


    submatrix
    难度级别: A; 编程语言:不限;运行时间限制:2000ms; 运行空间限制:131072KB; 代码长度限制:102400B
    试题描述
     
    小A有一个N×M的矩阵,矩阵中1~N*M这(N*M)个整数均出现过一次。现在小A在这个矩阵内选择一个子矩阵,其权值等于这个子矩阵中的所有数的最小值。小A想知道,如果他选择的子矩阵的权值为i(1<=i<=N×M),那么他选择的子矩阵可能有多少种?小A希望知道所有可能的i值对应的结果,但是这些结果太多了,他算不了,因此他向你求助。
    输入
    第一行,两个整数N, M。
    接下来的N行,每行M个整数,表示矩阵中的元素。
    输出
    N×M行,每行一个整数,其中第i行的整数表示如果小A选择的子矩阵权值为i,他选择的子矩阵的种类数。
    输入示例
    2 3
    2 5 1
    6 3 4
    输出示例
    6
    4
    5
    1
    1
    1
    其他说明
    对于30%的数据,1<=N, M<=50;
    对于全部的数据,1<=N, M<=300。
     

    题解:%%%郑爷,先考虑一维,用单调栈维护一下可以到左边右边,更新答案。对于二维,把一维拍扁就可以了。。。。记得是取最小值。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=300+10,maxans=90000+10,inf=-1u>>1;
    11 int A[maxn][maxn],mi[maxn],R[maxn],L[maxn],s[maxn],pos[maxn],p[maxans],n,m;
    12 inline int read(){
    13     int x=0,sig=1;char ch=getchar();
    14     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
    15     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
    16     return sig?x:-x;
    17 }
    18 inline void write(int x){
    19     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    20     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    21     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    22 }
    23 void init(){
    24     n=read();m=read();
    25     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)A[i][j]=read();
    26     for(int i=1;i<=n;i++){
    27         for(int j=1;j<=m;j++)mi[j]=inf;
    28         for(int j=i;j<=n;j++){
    29             for(int k=1;k<=m;k++)mi[k]=min(mi[k],A[j][k]);int top=0;
    30             for(int k=1;k<=m;k++){//
    31                 while(top&&(mi[k]<s[top]))R[pos[top--]]=k-1;
    32                 s[++top]=mi[pos[top]=k];
    33             }while(top)R[pos[top--]]=m;
    34             for(int k=m;k>=1;k--){//
    35                 while(top&&(mi[k]<s[top]))L[pos[top--]]=k+1;
    36                 s[++top]=mi[pos[top]=k];
    37             }while(top)L[pos[top--]]=1;
    38             for(int k=1;k<=m;k++)p[mi[k]]+=(R[k]-k+1)*(k-L[k]+1);
    39         }
    40     }int all=n*m;for(int i=1;i<=all;i++)write(p[i]),ENT;
    41     return;
    42 }
    43 void work(){
    44     return;
    45 }
    46 void print(){
    47     return;
    48 }
    49 int main(){init();work();print();return 0;}
  • 相关阅读:
    QT,QVector 基本用法,遍历[实例讲解]
    QT boolinq
    Qt532.QString_填充字符
    QT AES加密
    允许ubuntu下mysql远程连接
    Curl参数一览
    PHP实现http与https转化
    LINUX查看硬件配置命令
    使用.htaccess的时候服务器出现500错误(在配置后台时出现)
    64位win7旗舰版搭建apache+php+mysql开发环境
  • 原文地址:https://www.cnblogs.com/chxer/p/4720694.html
Copyright © 2020-2023  润新知