九度1497:面积最大的全1子矩阵

题目描述:

在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多。

输入:

输入可能包含多个测试样例。

对于每个测试案例,输入的第一行是两个整数m、n(1<=m、n<=1000):代表将要输入的矩阵的大小。

矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开。

输出:

对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数。

样例输入:
2 2
0 0
0 0
4 4
0 0 0 0
0 1 1 0
0 1 1 0
0 0 0 0
样例输出:
0
4


先统计出每一行的连续1个数
例如
1 1 1 1 1 0 1
0 0 1 1 0 1 1 
0 0 1 1 1 0 1
1 1 0 0 1 0 0
得到
1 2 3 4 5 0 1
0 0 1 2 0 1 1
0 0 1 2 3 0 1
1 2 0 0 1 0 0
然后按照列累加得到连续
1 2 5 8 5 0 3
0 0 5 8 0 1 3
0 0 5 8 4 0 3
1 2 0 0 4 0 0
这个是通过与maxn进行比较看是否要算的
然后如果有需要算的话,那么就看这个位置往下和网上走,找到在第二个矩形的情况这一列中小于这个数的时候退出
因为这个数是统计的横向过来的1的个数
只有在大于等于自身的时候,才能以现在这个长度来构建1矩阵
所以得到代码如下

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;

int map[1005][1005];
int col[1005][1005];
int n,m,maxn;

void set_col(int p)
{
    int i,j,sum;
    for(i = 1; i<=n; i++)
    {
        if(!map[i][p])
            continue;
        j = i;
        sum = 0;
        while(map[j][p] && j<=n)
        {
            sum+=map[j][p];
            j++;
        }
        for(int k = i; k<j; k++)
            col[k][p] = sum;
        i = j;
    }
}

int find(int r,int c)
{
    int i,j,val=map[r][c];
    int cnt = 1;
    for(i = r-1; i>0; i--)
    {
        if(val>map[i][c])
            break;
        cnt++;
    }
    for(i = r+1; i<=n; i++)
    {
        if(val>map[i][c])
            break;
        cnt++;
    }
    return val*cnt;
}

int solve()
{
    int i,j;
    maxn = 0;
    for(i = 1; i<=n; i++)
    {
        for(j = 1; j<=m; j++)
        {
            if(maxn<col[i][j] && map[i][j])
            {
                int val = find(i,j);
                maxn = max(maxn,val);
            }
        }
    }
    return maxn;
}

int main()
{
    int i,j;
    while(~scanf("%d%d",&n,&m))
    {
        for(i = 1; i<=n; i++)
        {
            for(j = 1; j<=m; j++)
                scanf("%d",&map[i][j]);
        }
        for(i = 1; i<=n; i++)
        {
            for(j = 2; j<=m; j++)
            {
                if(map[i][j]==1 && map[i][j-1])
                    map[i][j]=map[i][j-1]+1;
            }
        }
        for(i = 1; i<=m; i++)
            set_col(i);
        printf("%d\n",solve());
    }

    return 0;
}

时间: 2024-08-02 14:58:19

九度1497:面积最大的全1子矩阵的相关文章

九度OJ 1497:面积最大的全1子矩阵(DP)

题目1497:面积最大的全1子矩阵 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:850 解决:178 题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行是两个整数m.n(1<=m.n<=1000):代表将要输入的矩阵的大小. 矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开. 输出: 对应每个测试案例,输

面积最大的全1子矩阵--九度OJ 1497

题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行是两个整数m.n(1<=m.n<=1000):代表将要输入的矩阵的大小.矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开. 输出: 对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数. 样例输入: 2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0

[Jobdu] 题目1497:面积最大的全1子矩阵

题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行是两个整数m.n(1<=m.n<=1000):代表将要输入的矩阵的大小.矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开. 输出: 对应每个测试案例,输出矩阵中面积最大的全1子矩阵的元素个数. 样例输入: 2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0

面积最大的全1子矩阵

面积最大的全1子矩阵 时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:859 解决:179 题目描述: 在一个M * N的矩阵中,所有的元素只有0和1,从这个矩阵中找出一个面积最大的全1子矩阵,所谓最大是指元素1的个数最多. 输入: 输入可能包含多个测试样例.对于每个测试案例,输入的第一行是两个整数m.n(1<=m.n<=1000):代表将要输入的矩阵的大小.矩阵共有m行,每行有n个整数,分别是0或1,相邻两数之间严格用一个空格隔开. 输出: 对应每个测试案例,输出矩阵中面积最大的

剑指OFFER之调整数组顺序使奇数位于偶数前面找(九度OJ1516)

题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 输入: 每个输入文件包含一组测试案例.对于每个测试案例,第一行输入一个n,代表该数组中数字的个数.接下来的一行输入n个整数.代表数组中的n个数. 输出: 对应每个测试案例,输入一行n个数字,代表调整后的数组.注意,数字和数字之间用一个空格隔开,最后一个数字后面没有空格. 样例输入: 5 1 2 3 4 5 样例输

[ACM] 九度OJ 1553 时钟

时间限制:1 秒 内存限制:128 兆 特殊判题:否 提交:1733 解决:656 题目描述: 如图,给定任意时刻,求时针和分针的夹角(劣弧所对应的角). 输入: 输入包含多组测试数据,每组测试数据由一个按hh:mm表示的时刻组成. 输出: 对于每组测试数据,输出一个浮点数,代表时针和分针的夹角(劣弧对应的角),用角度表示,结果保留两位小数. 样例输入: 03:00 14:45 样例输出: 90.00 172.50 来源: 2014年王道论坛计算机考研机试全真模拟考试 解题思路: 求时针和分针的

剑指OFFER之最大子向量和(连续子数组的最大和)(九度OJ1372)

题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止).你会不会被他忽悠住? 输入: 输入有多组数据,每组测试数据包括两行. 第一行为一个整数n(0<=n<=100000),当

剑指OFFER之从上往下打印二叉树(九度OJ1523)

题目描述: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行一个整数n(1<=n<=1000, :n代表将要输入的二叉树元素的个数(节点从1开始编号).接下来一行有n个数字,代表第i个二叉树节点的元素的值.接下来有n行,每行有一个字母Ci.Ci='d'表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号.Ci='l'表示第i个节点有一个左孩子,紧接着是左孩子的编号.Ci='r'表示第i个节点有一个右孩

九度 1203

#include <cstdio> #include <iostream> using namespace std; #ifdef ONLINE_JUDGE #define FINPUT(file) 0 #define FOUTPUT(file) 0 #else #define FINPUT(file) freopen(file,"r",stdin) #define FOUTPUT(file) freopen(file,"w",stdout)