zoukankan      html  css  js  c++  java
  • [BZOJ1047][HAOI2007]理想的正方形

    1047: [HAOI2007]理想的正方形

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2230  Solved: 1188
    [Submit][Status][Discuss]

    Description

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

    Input

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

    Output

    仅一个整数,为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

    HINT

    问题规模

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

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

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

    Source

    这个题有很多解法,我用了效率不高的二维不优化RMQ(呵呵能AC真是奇迹),具体就是用$maxm[i][j][k]$表示左上角是$(i,j)$,大小为$2^k*2^k$的正方形中的最大值,最小值同样处理。之后仿照一维情况,倍增预处理,注意使用 long long 。最后输出时枚举左上角位置,计算并输出,总的时间复杂度大概是$O(ablog n+ab)$。

    /**************************************************************
        Problem: 1047
        User: bhiaib0gf
        Language: C++
        Result: Accepted
        Time:4420 ms
        Memory:110876 kb
    ****************************************************************/
     
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define log2(x) (log(x)/log(2))
    long long maxm[1001][1001][7],minm[1001][1001][7];
    int a,b,n;
    int readint()
    {
        int ans=0;
        char c;
        while (!isdigit(c=getchar()));
        do
        {
            ans=ans*10+c-'0';
            c=getchar();    
        } while (isdigit(c));
        return ans;
    }
    int main()
    {
        a=readint(),b=readint(),n=readint();
        for (int i=1;i<=a;i++)
            for (int j=1;j<=b;j++)
            {
                maxm[i][j][0]=readint();
                minm[i][j][0]=maxm[i][j][0];
            }
        for (int i1=1;i1<=log2(n);i1++)
        {
            for (int i=1;i+(1<<i1)-1<=a;i++)
                for (int j=1;j+(1<<i1)-1<=b;j++)
                {
                    maxm[i][j][i1]=max(
                        max(
                            maxm[i][j][i1-1],
                            maxm[i+(1<<(i1-1))][j][i1-1]
                        ),
                        max(
                            maxm[i][j+(1<<(i1-1))][i1-1],
                            maxm[i+(1<<(i1-1))][j+(1<<(i1-1))][i1-1]
                        )
                    );
                    minm[i][j][i1]=min(
                        min(
                            minm[i][j][i1-1],
                            minm[i+(1<<(i1-1))][j][i1-1]
                        ),
                        min(
                            minm[i][j+(1<<(i1-1))][i1-1],
                            minm[i+(1<<(i1-1))][j+(1<<(i1-1))][i1-1]
                        )
                    );
                }
        }
        long long ans=(1<<31);
        ans*=ans;
        for (int i=1;i+n-1<=a;i++)
            for (int j=1;j+n-1<=b;j++)
            {
                int ls=int(log2(n));
                int maxnumber=max(
                    max(
                        maxm[i][j][ls],
                        maxm[i+n-(1<<ls)][j][ls]
                    ),max(
                        maxm[i][j+n-(1<<ls)][ls],
                        maxm[i+n-(1<<ls)][j+n-(1<<ls)][ls]
                    )
                );
                int minnumber=min(
                    min(
                        minm[i][j][ls],
                        minm[i+n-(1<<ls)][j][ls]
                    ),min(
                        minm[i][j+n-(1<<ls)][ls],
                        minm[i+n-(1<<ls)][j+n-(1<<ls)][ls]
                    )
                );
                if (maxnumber-minnumber<ans)
                    ans=maxnumber-minnumber;
            }
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:
    OK335x mksd.sh hacking
    Qt jsoncpp 对象拷贝、删除、函数调用 demo
    OK335xS 256M 512M nand flash make ubifs hacking
    Qt QScrollArea and layout in code
    JsonCpp Documentation
    Qt 4.8.5 jsoncpp lib
    Oracle数据库生成UUID
    freemarker得到数组的长度
    FreeMarker中if标签内的判断条件
    freemarker语法
  • 原文地址:https://www.cnblogs.com/changke/p/4993018.html
Copyright © 2011-2022 走看看