zoukankan      html  css  js  c++  java
  • 理想的正方形 HAOI2007(二维RMQ)

    理想的正方形

     

    省队选拔赛河南

     时间限制: 1 s
     空间限制: 256000 KB
     题目等级 : 大师 Master
     
     
     
    题目描述 Description

        有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

    输入描述 Input Description

        第一行为3个整数,分别表示a,b,n的值

        第二行至第a+1行每行为b个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。

    输出描述 Output Description

     仅一个整数,为a*b矩阵中所有“n*n正方形区域中的最大整数和最小整数的差值”的最小值。

    样例输入 Sample Input

    5 4 2

    1 2 5 6

    0 17 16 0

    16 17 2 1

    2 10 2 1

    1 2 2 2

    样例输出 Sample Output

    1

    数据范围及提示 Data Size & Hint

    (1)矩阵中的所有数都不超过1,000,000,000

    (2)20%的数据2<=a,b<=100,n<=a,n<=b,n<=10

    (3)100%的数据2<=a,b<=1500,n<=a,n<=b,n<=100

    /*
    嗯,脑补二维RMQ fail,挂成暴力分。
    一维是维护一个区间,二维是维护一个矩阵。
    由于这个题是小正方形,三维数组即可。二维RMQ略麻烦... 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    
    #define x2 x1+n-1-(1<<m)+1
    #define y2 y1+n-1-(1<<m)+1
    
    using namespace std;
    void read(int &x)
    {
        int f=1;x=0;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=(x<<3)+(x<<1)+c-'0';c=getchar();}
        x*=f;
    }
    
    void out(int x)
    {
        if(!x){putchar('0');return;}
        if(x<0){x=~x+1;putchar('-');}
        char c[30]= {0};
        while(x)c[++c[0]]=x%10+48,x/=10;
        while(c[0])putchar(c[c[0]--]);
    }
    const int inf=1e3+29;
    int i,j,k,m;
    int g[inf][inf][12];
    int f[inf][inf][12];
    int x,y,n;
    int ans=0x7fffffff;
    
    int query(int x1,int y1)
    {
        int maxn=0,minn=0x7fffffff;
        maxn=max(f[x1][y1][m],f[x2][y2][m]);
        maxn=max(maxn,f[x1][y2][m]);
        maxn=max(maxn,f[x2][y1][m]);
        minn=min(g[x1][y1][m],g[x2][y2][m]);
        minn=min(minn,g[x1][y2][m]);
        minn=min(minn,g[x2][y1][m]);
        return maxn-minn;
    }
    
    int main()
    {
        read(y);read(x);
        read(n);m=log(n)/log(2);
        for(i=1; i<=y; i++)
          for(j=1; j<=x; j++)
            {
                read(f[j][i][0]);
                g[j][i][0]=f[j][i][0];
            }
        for(k=1; k<=12; k++)
          for(i=1; i+(1<<k)-1<=x; i++)
            for(j=1; j+(1<<k)-1<=y; j++)
            {
                f[i][j][k]=max(f[i][j][k-1],f[i+(1<<(k-1))][j+(1<<(k-1))][k-1]);
                f[i][j][k]=max(f[i][j][k],f[i+(1<<(k-1))][j][k-1]);
                f[i][j][k]=max(f[i][j][k],f[i][j+(1<<(k-1))][k-1]);
                g[i][j][k]=min(g[i][j][k-1],g[i+(1<<(k-1))][j+(1<<(k-1))][k-1]);
                g[i][j][k]=min(g[i][j][k],g[i+(1<<(k-1))][j][k-1]);
                g[i][j][k]=min(g[i][j][k],g[i][j+(1<<(k-1))][k-1]);
            }
        for(i=1; i+n-1<=x; i++)
          for(j=1; j+n-1<=y; j++)
            ans=min(ans,query(i,j));
        out(ans);
        return 0;
    }
    折花枝,恨花枝,准拟花开人共卮,开时人去时。 怕相思,已相思,轮到相思没处辞,眉间露一丝。
  • 相关阅读:
    HBase(九)HBase表以及Rowkey的设计
    iOS-动态库创建(详解)
    组件化-动态库实战
    Xcode创建子工程以及工程依赖
    XMPP详解
    iOS中WebKit框架应用与解析
    HYStockChart, 股票图(包括K线图、趋势图、成交量、滚动、放大缩小等)
    OC与JS交互
    iOS 与 js交互的其一方法 WebViewJavascriptBridge的使用
    OC和JS调用
  • 原文地址:https://www.cnblogs.com/L-Memory/p/7719132.html
Copyright © 2011-2022 走看看