zoukankan      html  css  js  c++  java
  • [HNOI2007] 理想正方形 二维ST表

    题目描述

    有一个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表,没学会,先留着坑,以后学


    #include <iostream>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    int a, b, n;
    int tt;
    int STn[1001][1001];
    int STx[1001][1001]; 
    int G[1001][1001];
    int ans = 0x7f7f7f7f;
    
    inline int Query(int x, int y)
    {
        int maxx = 0, minn = 0;
        maxx = max(STx[x][y], max(STx[x - (1<<tt) + n][y], max(STx[x][y - (1<<tt) + n], STx[x - (1<<tt) + n][y - (1<<tt) + n]))) ;
        minn = min(STn[x][y], min(STn[x - (1<<tt) + n][y], min(STn[x][y - (1<<tt) + n], STn[x - (1<<tt) + n][y - (1<<tt) + n]))) ;
        return maxx - minn;
    }
    
    int main()
    {
        scanf("%d%d%d", &a, &b, &n);
        tt = log(n) / log(2);
        for (register int i = 1 ; i <= a ; i ++)
        {
            for (register int j = 1 ; j <= b ; j ++)
            {
                int x;scanf("%d", &x);G[i][j] = x;
                STn[i][j] = STx[i][j] = x;
            }
        }
        for (register int k = 0 ; k < tt ; k ++)
        {
            for (register int i = 1 ; i <= a ; i ++)
            {
                if (i + (1<<k) > a) continue;
                for (register int j = 1 ; j <= b ; j ++)
                {
                    if (j + (1<<k) > b) continue;
                    STn[i][j] = min(STn[i][j], min(STn[i + (1<<k)][j + (1<<k)], min(STn[i + (1<<k)][j], STn[i][j + (1<<k)])));
                    STx[i][j] = max(STx[i][j], max(STx[i + (1<<k)][j + (1<<k)], max(STx[i + (1<<k)][j], STx[i][j + (1<<k)])));
                }
            }
        }
        for (register int i = 1 ; i <= a - n + 1 ; i ++)
        {
            for (register int j = 1 ; j <= b - n + 1 ; j ++)
            {
                ans = min(ans, Query(i, j));
            }
        }
        cout << ans;
        return 0;
    }
  • 相关阅读:
    十七、mysql数据库备份
    消费端ACK和重回队列
    RabbitMQ TTL、死信队列
    消费端限流策略
    029异常处理
    028class_part2
    027class_part1
    026json和pickle,xml模块
    025__name__变量和目录结构规范
    024模块的概念
  • 原文地址:https://www.cnblogs.com/BriMon/p/9281438.html
Copyright © 2011-2022 走看看