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

题目描述:

一个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

首先这个题应该是有一个动态规划的解法,不过好像复杂度也要到O(n^3logn),所以这里直接暴力了。但是为了节省时间首先计算出从左上角开始的矩阵的和,然后根据这个和可以求各个矩阵的值

 1 //计算左上角为(1,1)的所有子矩阵的和,需要O(N^2)的时间。
 2 //此时只需要O(1)的时间就可以算出每个子矩阵的和。
 3 //枚举次数依然不变。总时间复杂度为O(N^4)
 4 #include<iostream>
 5 #include<cstdio>
 6 #include<cstring>
 7 using namespace std;
 8 int main()
 9 {
10     //freopen("t","r",stdin);
11     int m,n,k;
12     while(cin>>m>>n>>k){
13         int ma[105][105];
14         for(int i=0;i<m;i++){
15             for(int j=0;j<n;j++){
16                 cin>>ma[i][j];
17             }
18         }
19         int sum[105][105];
20         memset(sum,0,sizeof(sum));
21         sum[0][0]=ma[0][0];
22         for(int i=1;i<m;i++){
23             sum[i][0]=ma[i][0]+sum[i-1][0];
24         }
25         for(int i=1;i<n;i++){
26             sum[0][i]=ma[0][i]+sum[0][i-1];
27         }
28         for(int i=1;i<m;i++){
29             for(int j=1;j<n;j++){
30                 sum[i][j]+=sum[i][j-1];
31                 for(int k=0;k<=i;k++){
32                     sum[i][j]+=ma[k][j];
33                 }
34             }
35         }
36
37         int minsize=999999;
38         for(int a=0;a<m;a++){
39             for(int b=a;b<m;b++){
40                 for(int c=0;c<n;c++){
41                     for(int d=c;d<n;d++){
42                         int s=0;
43                         if(a==0&&b==0&&c==0&&d==0){
44                             s=sum[0][0];
45                         }
46                         else if(a==0&&c==0){
47                             s=sum[b][d];
48                         }
49                         else if(a==0){
50                             s=sum[b][d]-sum[b][c-1];
51                         }
52                         else if(c==0){
53                             s=sum[b][d]-sum[a-1][d];
54                         }
55                         else{
56                             s=sum[b][d]+sum[a-1][c-1]-sum[a-1][d]-sum[b][c-1];
57                         }
58                         if(s>=k){
59                             int sizee=(b-a+1)*(d-c+1);
60                             if(minsize>sizee){
61                                 minsize=sizee;
62                             }
63                         }
64                     }
65                 }
66             }
67         }
68         if(minsize==999999){
69             cout<<-1<<endl;
70         }
71         else{
72             cout<<minsize<<endl;
73         }
74     }
75     return 0;
76 }

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

时间: 2024-10-23 14:54:10

一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵的相关文章

[算法学习]给定一个整型数组,找出两个整数为指定整数的和(3)

问题描述: 设计一个类,包含如下两个成员函数: Save(int input) 插入一个整数到一个整数集合里. Test(int target) 检查是否存在两个数和为输入值.如果存在着两个数,则返回true,否则返回false 允许整数集合中存在相同值的元素 分析: 与[算法学习]给定一个整型数组,找出两个整数为指定整数的和(2)不同,这里需要算出的是存不存在这两个数,可以在上一篇的基础上修改一下数据结构,HashMap其中key是数值,value是数值个数,然后需要作两步判断,map中存在数

给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length

// 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 /* Input: set[] = {'a', 'b'}, k = 3 Output: aaa aab aba abb baa bab bba bbb Input: set[] = {'a', 'b', 'c', 'd'}, k = 1 Output: a b c d package recursion; import java.util.ArrayList; public class N_sets_form

【leetcode-03】给定一个字符串,请你找出其中不含有重复字符的最长子串的长度

开个新坑,leetcode上面做题目.下面是题目描述: <!-- 给定一个字符串,请你找出其中不含有重复字符的最长子串的长度. 示例 1: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3. 示例 2: 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1. 示例 3: 输入: "pwwkew" 输出

delphi程序向另一个可执行程序发消息(使用GetForegroundWindow; 找出当前操作系统中活动的第一个窗口)

function FindWindowThroughWindowText(WindowText: string): THandle;var  hCurrentWindow: THandle;  cnt: Integer;  WindowTitle: array [0 .. 254] of Char;begin  Result := INVALID_HANDLE_VALUE; // 返回值预设为无效的句柄  hCurrentWindow := GetForegroundWindow; // 找出当

Entity Framework 6 Recipes 2nd Edition(9-3)译-&gt;找出Web API中发生了什么变化

9-3. 找出Web API中发生了什么变化 问题 想通过基于REST的Web API服务对数据库进行插入,删除和修改对象图,而不必为每个实体类编写单独的更新方法. 此外, 用EF6的Code Frist实现数据访问管理. 本例,我们模拟一个N层场景,用单独的客户端(控制台应用)来调用单独的基于REST服务的Web网站(WEB API应用) . 注意:每层使用单独的Visual Studio 解决方案, 这样更方便配置.调试和模拟一个N层应用. 假设有一个如Figure 9-3所示的旅行社和预订

找出十进制数中出现的&#39;&#39;一&#39;&#39;的个数

一.题目要求: 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 1.写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12)  = 5. 2.在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少. 二.解决思路 通过列举几个数进行计算,可以发现函数f(N)规律如下: 1.一位十进制数:当N>=1时,f(N)=1:当N=0时,f(N)= 0; 2.两位十进制数:f(13)=个位出现1的个数+十位出现1的个数=2+4

笔试算法题(24):找出出现次数超过一半的元素 &amp; 二叉树最近公共父节点

出题:数组中有一个数字出现的次数超过了数组长度的一半,请找出这个数字: 分析: 解法1:首先对数组进行排序,时间复杂度为O(NlogN),由于有一个数字出现次数超过了数组的一半,所以如果二分数组的话,划分元素肯定就是这个数字: 解法2:首先创建1/2数组大小的Hash Table(哈希表可以替代排序时间,由于一个数字出现超过了数组的一半,所以不同元素个数肯定不大于数组的一半),空间复杂度O(N),顺序扫描映射数 组元素到Hash Table中并计数,最后顺序扫描Hash Table,计数超过数组

[算法]找出数组当中的中枢元素

给定一个整型数组,找出pivot,使得对于任意i < pivot,a[i] <=a[pivot],对于i > pivot,a[i]>=a[pivot],只能用一个额外的数组,和少量空间. 思路 1.使用一个数组t记录,t[i]记录的是a[0]~a[i]的最大值 int *t = new int[n]; for(int i = 0, max = ~0; i < n; ++i){ if(a[i] > max){ max = a[i]; } t[i] = max; } 2.从

找出该字符串中出现次数最多的那个字符

/*时间限制 C/C++ 3s 其他 6s, 空间限制 C/C++ 32768k 其他 65535k 题目描述     给定一个长度不限的字符串,请找出该字符串中出现次数最多的那个字符,并打印出该字符及其出现次数; 如果多个字符的出 现次数相同,只打印首个字符;输出字符的大小写格式要与输 入保持一致,大小写不敏感模式下, 输出字符的大小写格式与该 字符首次出现时的大小写格式一致.实现时无需考虑非法输. 输入描述     输入为 字符串大小写敏感标记 其中"大小写敏感标记"为可选参数,取