魔法学徒
时间限制(普通/Java) : 2000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 20 测试通过 : 6 描述
这里有一个N*M的大型矩阵,当中充满了0或1。 小魔法师phk童鞋想从这个大型矩阵中找出一个最大子矩阵,并且这个最大子矩阵全部由1组成。 当然当了18年蹩脚的魔法学徒,他总是有那么点特殊能力的。虽然魔力有限,但他还是能施展一次变换术,这招可以毫无道理地将大型矩阵中的一整行全部变成1,然后再去找最大子矩阵。 尽管这样,但phk童鞋还是很难从大型矩阵中找到最大子矩阵,所以请你帮忙寻找。
输入
这里有多组测试数据,第一行为两个数字,N,M(1<=N,M<=100),接下来N*M个整数,表示一个矩阵。 输出
输出最大的子矩阵大小。 样例输入 2 2 样例输出 4 提示
题目来源 HLY |
题目地址:http://218.194.91.48/acmhome/problemdetail.do?&method=showdetail&id=1303
利用到这题的一点思路:http://blog.csdn.net/diannaok/article/details/7796441
其余就是纯暴力枚举了。。。
===========================================================================================================
以前的搓B写法:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
char mp[103][103];
int dp[103][103];
int l[103],r[103];
int main(){
int i,j,k,n,m,mx,tmp;
while(~scanf("%d%d",&n,&m)){
for(i=1;i<=n;i++) scanf("%s",mp[i]+1);
mx=0;
for(j=1;j<=m;j++) dp[0][j]=0;
for(k=1;k<=n;k++){
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
if(i==k || mp[i][j]=='1') dp[i][j]=dp[i-1][j]+1;
else dp[i][j]=0;
for(i=1;i<=n;i++){
for(j=0;j<=m+1;j++) l[j]=r[j]=j;
dp[i][0]=dp[i][m+1]=-1;
for(j=1;j<=m;j++)
while(dp[i][l[j]-1]>=dp[i][j])
l[j]=l[l[j]-1];
for(j=m;j>=1;j--)
while(dp[i][r[j]+1]>=dp[i][j])
r[j]=r[r[j]+1];
for(j=1;j<=m;j++){
tmp=(r[j]-l[j]+1)*dp[i][j];
if(tmp>mx) mx=tmp;
}
}
}
printf("%d\n",mx);
}
return 0;
}
===========================================================================================================
新学的写法:
#include<iostream>
#include<cstdio>
using namespace std;
char s[102][102];
int n,m;
short get_res(){
short h[102],l[102],r[102],i,j,lm,rm,k,res=0,tmp;
for(k=0;k<n;k++){
for(j=0;j<m;j++)
h[j]=0,l[j]=0,r[j]=m-1;
for(i=0;i<n;i++){
lm=0,rm=m-1;
for(j=0;j<m;j++)
if(s[i][j]=='1' || k==i){
h[j]++;
if(lm>l[j]) l[j]=lm;
}
else lm=j+1,h[j]=0,l[j]=0;
for(j=m-1;j>=0;j--)
if(h[j]){
if(rm<r[j]) r[j]=rm;
tmp=(r[j]-l[j]+1)*h[j];
if(tmp>res) res=tmp;
}
else rm=j-1,r[j]=m-1;
}
}
return res;
}
int main(){
while(~scanf("%d%d",&n,&m)){
for(int i=0;i<n;i++) scanf("%s",s[i]);
printf("%d\n",get_res());
}
return 0;
}