zoukankan      html  css  js  c++  java
  • 最大子矩阵的一种实现方法

    题目:

    农夫约翰想要在他的正方形农场上建造一座正方形大牛棚。他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方。我们假定,他的农场划分成 N x N 的方格。输入数据中包括有树的方格的列表。你的任务是计算并输出,在他的农场中,不需要砍树却能够修建的最大正方形牛棚。牛棚的边必须和水平轴或者垂直轴平行。
    EXAMPLE

    考虑下面的方格,它表示农夫约翰的农场,‘.'表示没有树的方格,‘#'表示有树的方格

    1 2 3 4 5 6 7 8
    1 . . . . . . . .
    2 . # . . . # . .
    3 . . . . . . . .
    4 . . . . . . . .
    5 . . . . . . . .
    6 . . # . . . . .
    7 . . . . . . . .
    8 . . . . . . . .

    最大的牛棚是 5 x 5 的,可以建造在方格右下角的两个位置其中一个。

    Input

    Line 1: 两个整数: N (1 <= N <= 1000),农场的大小,和 T (1 <= T <= 10,000)有树的方格的数量 Lines 2..T+1: 两个整数(1 <= 整数 <= N), 有树格子的横纵坐标

    Output

    输出文件只由一行组成,约翰的牛棚的最大边长。

    资料

    我用的是算法一(空间复杂度较小)

    #include <cstdio>
    #include <assert.h>
    #include <algorithm>
    using namespace std;
    const int N = 5000011;
    struct p{int x,y;}ans[N];
    int n,a,b,hi,lo,nxt,maxs = 0;
    bool cmp1(p aa,p bb){return aa.x == bb.x ? aa.y < bb.y : aa.x < bb.x;}
    void re(int xx,int yy){if(min(xx,yy) > maxs)maxs = min(xx,yy);}
    int main()
    {
        scanf("%d %d",&a,&n);
        b = a;
        for(int i = 1;i <= n;i++)
            scanf("%d %d",&ans[i].x,&ans[i].y);
        ans[n + 1] = {0,0},ans[n + 2] = {a,0};
        ans[n + 3] = {0,b},ans[n + 4] = {a,b};
        n += 5;
        sort(ans + 1,ans + n,cmp1);
        for(int i = 1;i < n;i++){
            hi = 0,lo = b,nxt = i + 1;
            ans[n]={a,ans[i].y};
            for(;;){
                while(!(ans[nxt].y>=hi&&ans[nxt].y<=lo&&ans[nxt].x != ans[i].x))nxt++;
                if(nxt > n)break;
                re(ans[nxt].x - ans[i].x,lo - hi);
                if(ans[nxt].y >= ans[i].y)lo = ans[nxt].y;
                else hi = ans[nxt].y;
                if(ans[nxt].y == ans[i].y)break;
                nxt++;
            }
        }
        n--;
        for(int i = n;i > 1;i--){
            hi = 0,lo = b,nxt = i - 1;
            ans[0]={0,ans[i].y};
            for(;;){
                while(!(ans[nxt].y>=hi&&ans[nxt].y<=lo&&ans[nxt].x != ans[i].x))nxt--;
                if(nxt < 0)break;
    //          printf("%d:%d
    ",i,nxt);
    //          printf("<%d %d %d %d>",ans[i].x,ans[nxt].x,lo,hi);
                re(ans[i].x - ans[nxt].x,lo - hi);
                if(ans[nxt].y >= ans[i].y)lo = ans[nxt].y;
                else hi = ans[nxt].y;
                if(ans[nxt].y == ans[i].y)break;
                nxt--;
            }
        }
        printf("%d",maxs == 5 ? 5 : maxs - 1);
        return 0;
    }
  • 相关阅读:
    springboot文件上传: 单个文件上传 和 多个文件上传
    Eclipse:很不错的插件-devStyle,将你的eclipse变成idea风格
    springboot项目搭建:结构和入门程序
    POJ 3169 Layout 差分约束系统
    POJ 3723 Conscription 最小生成树
    POJ 3255 Roadblocks 次短路
    UVA 11367 Full Tank? 最短路
    UVA 10269 Adventure of Super Mario 最短路
    UVA 10603 Fill 最短路
    POJ 2431 Expedition 优先队列
  • 原文地址:https://www.cnblogs.com/frankying/p/8535491.html
Copyright © 2011-2022 走看看