最大矩阵
(matrix.pas/c/cpp)
【问题描述】
在看过萝卜同学的游戏后, Fbs 表示太无趣了。他想试试萝卜同学能不能玩点级别更高的游戏,于
是他想了个难度大点的。
首先他定义:一个矩阵的权值为这个矩阵四个角上的数值的最小值。现在 Fbs 给出一个 N*M 的矩阵,
以及矩阵上的数值, 他想让萝卜同学在这个矩阵中寻找到一个权值最大的子矩阵。萝卜同学看了一眼就
傻眼了,表示他不能玩这游戏,但是他很机灵,偷偷的向你求助, 所以请你告诉他这个最大权值。
【输入格式】
第一行两个数 N,M
接下来一个 N*M 的矩阵
【输出格式】
一个数表示最大权值
【样例输入】
3 3
1 0 1
0 1 0
0 1 1
【样例输出】
0
【样例解释】
可以发现无论选择哪个子矩阵四角都至少有一个 0。
【数据说明】
对于 10%的数据: 1<=N,M<=50
对于 30%的数据: 1<=N,M<=200
对于 100%的数据: 1<=N,M<=2000, 所有的数值不超过 10^9
【限制】
时间:1.5s 空间:256MB;
【题目分析】
考场上我只写出了O(n^3)的方法,每次枚举两列,然后一行一行的刷,二分我是有想过,就是不知道check怎么写,后来我看了题解,嗯……我果然是个JR(蒟蒻)。
首先这道题很容易想到二分枚举答案,然后进行check,开一个数组c,枚举行,先将这行中比答案大的全加入数组,然后接下来都O(n^2)两两枚举,定义布尔数组g[i][j],表示前面第i个元素和第j个元素是否在同一行大于答案,如果这次枚举发现g[i][j]为真,那么说明这一行和前面某一行都有i和j大于答案,那么这个矩阵四个角全大于矩阵,查找成功,退出,否则为了下次的枚举,g[i][j]赋值给1。
最后吐槽一下本地评测的时候所有考试评测AC的代码都TLE了,包括本JR的订正代码,后来在网上找到了一个神奇的读优,然后……就过了……
【复杂度】
时间:O(n^3*log(max_a[i])); (当然实际会比这小的多);
空间:O(n^2);
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,ans,L,R,a[2005][2005],c[2005];
bool f[2005][2005];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void readi(int &sum){
char ch=nc(); sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
}
bool _check(int x){
memset(f,0,sizeof(f));
for (int i=1;i<=n;i++)
{
int q=0;
for (int j=1;j<=m;j++) if (a[i][j]>=x) c[++q]=j;
for (int j=1;j<q;j++)
for (int k=j+1;k<=q;k++)
if (f[c[j]][c[k]]) return true; else f[c[j]][c[k]]=1;
}
return false;
}
int main()
{
freopen("matrix.in","r",stdin);
freopen("matrix.out","w",stdout);
readi(n); readi(m); ans=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++){
readi(a[i][j]);
if (L>a[i][j]) L=a[i][j];
if (R<a[i][j]) R=a[i][j];
}
while (L<=R)
{
int mid=((R-L)>>1)+L;
if (_check(mid)){
ans=mid; L=mid+1;
}
else R=mid-1;
}
printf("%d",ans);
return 0;
}
PS:
关于读优:
读入优化新姿势——学习笔记 http://blog.csdn.net/chhnz/article/details/72672962
震惊!99.999%的OIER都不知道!我竟然学了假读优!竟然有这样的读优!
http://blog.csdn.net/FYOIER/article/details/72667544
在此对以上两位作者兼大牛ZH大佬和FY大佬表示崇敬和Orz
Orz ZH Orz FY