时间限制:1 秒

内存限制:32 兆

特殊判题:否

提交:1666

解决:504

题目描述:

一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积)

输入:

每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K

接下来N行,每行M个数,表示矩阵每个元素的值

输出:

输出最小面积的值。如果出现任意矩阵的和都小于K,直接输出-1。

样例输入:
4 4 10
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
样例输出:
1
来源:
2010年上海交通大学计算机研究生机试真题

思路:

暴力求解必然超时。此题在计算过程中有大量重复计算数据,应该进行缓存,有效利用,我的思路是b[i][j]保存第j列前i行的数之和,计算子矩阵和的时候,调用前一个sum与相应的b中元素计算。另外对于area大于当前搜索到的最小area的情况,不需要再搜索。

利用这些缓存和剪枝,我的代码运行时间从一开始的超时到最后的30ms。

运行编号 用户 问题 结果 详情 内存 代码长度 耗时 语言 提交时间
1368679 liangrx06 1102 Accepted 1028KB 1397B 30MS C++ / 代码 / 编辑 17:16:12
1360553 liangrx06 1102 Accepted 912KB 1170B 140MS C / 代码 / 编辑 17:16:27
1360547 liangrx06 1102 Accepted 952KB 1094B 730MS C / 代码 / 编辑 17:02:51
1360543 liangrx06 1102 Wrong Answer 952KB 1042B 740MS C / 代码 / 编辑 16:59:39
1360542 liangrx06 1102 Wrong Answer 952KB 1044B 800MS C / 代码 / 编辑 16:58:00
1360535 liangrx06 1102 Memory Limit Exceed 391428KB 1230B 0MS C / 代码 / 编辑 16:48:23
1360529 liangrx06 1102 Time Limit Exceed 912KB 1198B >1000MS C / 代码 / 编辑 16:36:53

其他人最好的运行时间是10ms,我没有再深入研究。我的代码应该仍有一定的优化余地。

代码:

#include <stdio.h>

#define N 100

int main(void)
{
int n, m, k;
int a[N][N], b[N][N];
int i, j, ii, jj;
int min, sum, area; while (scanf("%d%d%d", &n, &m, &k) != EOF)
{
for(i=0; i<n; i++)
{
for (j=0; j<m; j++)
{
scanf("%d", &a[i][j]);
if (i == 0)
b[i][j] = a[i][j];
else
b[i][j] = b[i-1][j] + a[i][j];
}
} min = N*N+1;
for(i=0; i<n; i++)
{
for (j=0; j<m; j++)
{
for (ii=i; ii<n; ii++)
{
sum = 0;
for (jj=j; jj<m; jj++)
{
area = (ii-i+1)*(jj-j+1);
if (area >= min)
break;
sum += b[ii][jj];
if (i > 0)
sum -= b[i-1][jj];
if (sum >= k)
min = area;
}
}
}
} if (min == N*N+1)
min = -1;
printf("%d\n", min);
} return 0;
}
/**************************************************************
Problem: 1102
User: liangrx06
Language: C
Result: Accepted
Time:30 ms
Memory:916 kb
****************************************************************/

代码2:

另一个人的10ms代码,我看了一下,跟我的代码总体思路不一样,但是利用的缓存粒度相同,而且他没有对面积剪枝,为什么时间这么短呢?

#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<stack>
#include<ctype.h>
#include<numeric>
using namespace std;
stack<int>stk;
int mat[110][110];
int h[110];
int calc(int n,int lim)
{
int ret=n+1,tmp;
int f=0,r=0,sum=0;
for(r=0;r<n;r++)
{
sum+=h[r];
while(sum>=lim)
{
tmp=r-f+1;
if(tmp<ret)ret=tmp;
sum-=h[f];
f++;
}
}
if(ret==n+1)return -1;
return ret;
}
int main()
{
int n,m,i,j;
int k;
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&mat[i][j]);
}
}
if(k<=0)
{
puts("0");
continue;
}
int ans=-1;
for(i=0;i<n;i++)
{
memset(h,0,sizeof(h));
for(j=i;j<n;j++)
{
for(int t=0;t<m;t++)
{
h[t]+=mat[j][t];
}
int tmp=calc(m,k)*(j-i+1);
if(tmp<0)continue;
if(ans==-1||tmp<ans)ans=tmp;
}
}
printf("%d\n",ans);
}
return 0;
} /**************************************************************
Problem: 1102
User: 鬼M
Language: C++
Result: Accepted
Time:10 ms
Memory:1072 kb
****************************************************************/

九度OJ 1102:最小面积子矩阵 (DP、缓存、剪枝)的更多相关文章

  1. 九度OJ 1371 最小的K个数 -- 堆排序

    题目地址:http://ac.jobdu.com/problem.php?pid=1371 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4 ...

  2. 九度OJ 1139:最大子矩阵 (矩阵运算、缓存)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1014 解决:376 题目描述: 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩 ...

  3. 九度OJ 1209 最小邮票数 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1209 题目描述: 有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值.     如,有1分,3分,3分,3 ...

  4. 九度OJ 1086 最小花费--动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1086 题目描述: 在某条线路上有N个火车站,有三种距离的路程,L1,L2,L3,对应的价格为C1,C2,C3.其对 ...

  5. 九度OJ 1091:棋盘游戏 (DP、BFS、DFS、剪枝)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1497 解决:406 题目描述: 有一个6*6的棋盘,每个棋盘上都有一个数值,现在又一个起始位置和终止位置,请找出一个从起始位置到终止位置代 ...

  6. 九度OJ 1082:代理服务器 (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:1871 解决:574 题目描述: 使用代理服务器能够在一定程度上隐藏客户端信息,从而保护用户在互联网上的隐私.我们知道n个代理服务器的IP地 ...

  7. 题目1102:最小面积子矩阵(暴力求解&最大连续子序列)

    题目链接:http://ac.jobdu.com/problem.php?pid=1102 详解链接:https://github.com/zpfbuaa/JobduInCPlusPlus 参考代码: ...

  8. 九度OJ 1502 最大值最小化(JAVA)

    题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...

  9. 【九度OJ】题目1187:最小年龄的3个职工 解题报告

    [九度OJ]题目1187:最小年龄的3个职工 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1187 题目描述: 职工有职工号,姓名, ...

随机推荐

  1. Drupal 有用的模块

    投票模块drigg https://www.drupal.org/project/drigg

  2. 通过房价预测入门Kaggle

    今天看了个新闻,说是中国社会科学院城市发展与环境研究所及社会科学文献出版社共同发布<房地产蓝皮书:中国房地产发展报告No.16(2019)>指出房价上涨7.6%,看得我都坐不住了,这房价上 ...

  3. jenkins发布普通项目、配置自动上线自动部署

    1.以root用户运行jenkins是不专业的 刚开始用jenkins时用jenkins这个普通用户运行程序,始终无法连接到gitlab,报错如下: 先是把修改jenkins上的git路径,将git修 ...

  4. JavaWeb过滤器.监听器.拦截器-?原理&区别

    过滤器可以简单理解为“取你所想取”,忽视掉那些你不想要的东西:拦截器可以简单理解为“拒你所想拒”,关心你想要拒绝掉哪些东西,比如一个BBS论坛上拦截掉敏感词汇. 1.拦截器是基于java的反射机制,过 ...

  5. 数组对象(NSArray和NSMutableArrray)

    Objective-C中除了可以使用C中的基本数组外,如int[5],char word[] ={‘a’,'b’,'c’};Foundation还提供了NSArray类.Foundation是有序的对 ...

  6. openfire Android学习(一)----实现用户注册、登录、修改密码和注销等

    以前学习过用Scoket 建立聊天,简单的建立聊天是没问题的,但如果要实现多人复杂的聊天,后台服务器代码就比较复杂,对于我这新手来讲就比较难了.后来在网上看到用openfire做服务器,利用强大的Sm ...

  7. paramiko获取远程主机的环境变量

    本文的情况,不同的linux系统版本,表现可能不同. 问题:默认情况下,paramiko在远程主机上执行命令的时候,命令的搜索路径为(/usr/local/bin:/bin:/usr/bin),这样我 ...

  8. sql的一些知识

    查询 查询表中的所有列(所有信息) SELECT * FROM userinfo 查询某一列(指定) select name from userinfo 查询某一列(指定,去重) SELECT DIS ...

  9. PS 如何用PS制作GIF图像

    首先我们准备好要依次播放的图片(这里使用的是CS的光标缩放,只有两张图) 然后在窗口中打开动画,则下方会出现动画的面板. 点击图层按钮可以添加一帧,我们让第一帧显示为大图片,第二帧为小图片.还可以设置 ...

  10. CUDA编程-&gt;CUDA入门了解(一)

    安装好CUDA6.5+VS2012,操作系统为Win8.1版本号,首先下个GPU-Z检測了一下: 看出本显卡属于中低端配置.关键看两个: Shaders=384.也称作SM.或者说core/流处理器数 ...