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;}
原文地址:https://www.cnblogs.com/chxer/p/4720694.html