zoukankan      html  css  js  c++  java
  • 【BZOJ1047】[HAOI2007]理想的正方形 (倍增ST表)

    [HAOI2007]理想的正方形

    题目描述

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

    输入输出格式

    输入格式:

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

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

    输出格式:

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

    输入输出样例

    输入样例#1:

    5 4 2
    1 2 5 6
    0 17 16 0
    16 17 2 1
    2 10 2 1
    1 2 2 2
    

    输出样例#1:

    1
    

    说明

    问题规模

    (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)

    题解

    刚学的二维(ST)表,和一维的大同小异。

    (mx[k][i][j])表示以((i,j))作为左上角,边长为(2^k)的正方形内的最大值。

    转移:

    $mx[k][i][j]=max(max(mx[k-1][i][j],mx[k-1][i][j+(1<<(k-1))]),max(mx[k-1][i+(1<<(k-1))][j],mx[k-1][i+(1<<(k-1))][j+(1<<(k-1))])); $

    最小值也是一样。

    最后(N^2)枚举左上角端点统计答案。

    code:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #define ll long long
    #define R register
    #define N 1005
    using namespace std;
    template<typename T>inline void read(T &a){
        char c=getchar();T x=0,f=1;
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        a=f*x;
    }
    int a,b,n,x,maxans,minans,ans=0x7fffffffLL,mx[11][N][N],mi[11][N][N];
    int main(){
        read(a);read(b);read(n);
        for(R int i=1;i<=a;i++)
            for(R int j=1;j<=b;j++)
                read(x),mi[0][i][j]=mx[0][i][j]=x;
        for(R int k=1;(1<<k)<=n;k++)
            for(R int i=1;i<=a-(1<<k)+1;i++)
                for(R int j=1;j<=b-(1<<k)+1;j++)
                    mi[k][i][j]=min(min(mi[k-1][i][j],mi[k-1][i][j+(1<<(k-1))]),min(mi[k-1][i+(1<<(k-1))][j],mi[k-1][i+(1<<(k-1))][j+(1<<(k-1))])),
                    mx[k][i][j]=max(max(mx[k-1][i][j],mx[k-1][i][j+(1<<(k-1))]),max(mx[k-1][i+(1<<(k-1))][j],mx[k-1][i+(1<<(k-1))][j+(1<<(k-1))]));
        R int k=(int)log2(n);
        for(R int i=1;i<=a-n+1;i++){
            for(R int j=1;j<=b-n+1;j++){
                minans=0x7fffffff;maxans=-0x7fffffff;
                maxans=max(max(mx[k][i][j],mx[k][i][j+n-(1<<k)]),max(mx[k][i+n-(1<<k)][j],mx[k][i+n-(1<<k)][j+n-(1<<k)]));
                minans=min(min(mi[k][i][j],mi[k][i][j+n-(1<<k)]),min(mi[k][i+n-(1<<k)][j],mi[k][i+n-(1<<k)][j+n-(1<<k)]));
                ans=min(maxans-minans,ans);
            }
        }
        printf("%d
    ",ans);	
        return 0;
    }
    
  • 相关阅读:
    python多线程多进程
    python单元测试unittest
    python学习笔记(一):python简介和入门
    今天的收获!!!
    Python django
    React router
    30分钟掌握ES6/ES2015核心内容
    webpack+React.js
    我喜欢的两个js类实现方式 现在再加上一个 极简主义法
    js实现的笛卡尔乘积-商品发布
  • 原文地址:https://www.cnblogs.com/ZAGER/p/9839554.html
Copyright © 2011-2022 走看看