码迷,mamicode.com
首页 > 其他好文 > 详细

[HAOI2007]理想的正方形

时间:2017-10-13 23:48:10      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:getchar   clu   min   getch   规模   ace   get   algo   while   

题目描述

有一个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表

st表能够维护数列的某个地方往后2的整数次方的极值

这个题目用st表来维护矩阵中某个元素往右下方二次方整数边长的矩阵元素的极值

然后四块合并    O1 查询四块原理就和ST表一样了 
*/


#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;

int maxx[1001][1001][13];
int minn[1001][1001][13];
int read()
{
    int num = 0;
    char c = getchar();
    while(c > 9 || c < 0)c = getchar();
    while(c <= 9 && c >= 0)
    {
        num *= 10;
        num += c - 0;
        c = getchar();
     } 
     return num;
}

int n,m,k,p;
int ans = 0x7fffffff;
int main()
{
    n = read();m = read();k = read();
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= m;j++)
            maxx[i][j][0] = minn[i][j][0] = read();
    p = log(k) / log(2);
    for(int i = 1;i <= 11;i++)
    {
        for(int j = 1;j + (1 << i) - 1 <= n;j++)
            for(int z = 1;z + (1 << i) - 1<= m;z++)
            {
                maxx[j][z][i] = 
                max(maxx[j][z][i - 1],
                max(maxx[j][z + (1 << (i - 1))][i - 1],
                max(maxx[j + (1 << (i - 1))][z + (1 << (i - 1))][i - 1],
                    maxx[j + (1 << (i - 1))][z][i - 1])));
                
                minn[j][z][i] = 
                min(minn[j][z][i - 1],
                min(minn[j][z + (1 << (i - 1))][i - 1],
                min(minn[j + (1 << (i - 1))][z + (1 << (i - 1))][i - 1],
                    minn[j + (1 << (i - 1))][z][i - 1])));
            }
    }
    for(int x = 1;x + k - 1 <= n;x++)
        for(int y = 1;y + k - 1 <= m;y++)
        {
                ans = min(ans,
            max(maxx[x][y][p],
            max(maxx[x][y + k - (1 << p)][p],
            max(maxx[x + k - (1 << p)][y][p],
                maxx[x + k - (1 << p)][y + k - (1 << p)][p]))) -
            min(minn[x][y][p],
            min(minn[x][y + k - (1 << p)][p],
            min(minn[x + k - (1 << p)][y][p],
                minn[x + k - (1 << p)][y + k - (1 << p)][p]))));
        }
    printf("%d",ans);
    return 0;
} 

 

[HAOI2007]理想的正方形

标签:getchar   clu   min   getch   规模   ace   get   algo   while   

原文地址:http://www.cnblogs.com/luoyibujue/p/7663500.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!