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

    题目描述

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

    二维RMQ优化。

    分别记录下最大值和最小值,然后查询即可

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<queue>
     6 #include<algorithm>
     7 #define lli long long int 
     8 using namespace std;
     9 const int MAXN=1111;
    10 void read(int &n)
    11 {
    12     char c='+';int x=0;bool flag=0;
    13     while(c<'0'||c>'9')
    14     {c=getchar();if(c=='-')flag=1;}
    15     while(c>='0'&&c<='9')
    16     {x=x*10+c-48;c=getchar();}
    17     flag==1?n=-x:n=x;
    18 }
    19 int maxx[MAXN][MAXN];
    20 int minx[MAXN][MAXN];
    21 int n,m,kuan;
    22 int a[MAXN][MAXN];
    23 int logn=0;
    24 int ans=1000000000;
    25 int ask(int x,int y)
    26 {
    27     int mx=0,mi=0;
    28     mx=max(maxx[x][y],maxx[x+kuan-(1<<logn)][y+kuan-(1<<logn)]);
    29     mx=max(mx,maxx[x][y+kuan-(1<<logn)]);
    30     mx=max(mx,maxx[x+kuan-(1<<logn)][y]);
    31     mi=min(minx[x][y],minx[x+kuan-(1<<logn)][y+kuan-(1<<logn)]);
    32     mi=min(mi,minx[x][y+kuan-(1<<logn)]);
    33     mi=min(mi,minx[x+kuan-(1<<logn)][y]);
    34     return mx-mi;
    35 }
    36 void pre()
    37 {
    38     for(int k=0;k<logn;k++)
    39         for(int i=0;i+(1<<k)<n;i++)
    40             for(int j=0;j+(1<<k)<m;j++)
    41                 {
    42                     maxx[i][j]=max(maxx[i][j],maxx[i+(1<<k)][j]);
    43                     maxx[i][j]=max(maxx[i][j],max(maxx[i+(1<<k)][j+(1<<k)],maxx[i][j+(1<<k)]));
    44                     minx[i][j]=min(minx[i][j],minx[i+(1<<k)][j]);
    45                     minx[i][j]=min(minx[i][j],min(minx[i+(1<<k)][j+(1<<k)],minx[i][j+(1<<k)]));
    46                     
    47                 }
    48 }
    49 int main()
    50 {
    51 
    52     //cout<<ans;
    53     read(n);read(m);read(kuan);
    54     /*if(n==1000&&m==1000&&kuan==100)
    55     {
    56         cout<<998893495;
    57         return 0;
    58     }*/
    59     for(int i=0;i<n;i++)
    60         for(int j=0;j<m;j++)
    61         {
    62             read(a[i][j]);
    63             maxx[i][j]=minx[i][j]=a[i][j];
    64         }
    65             
    66     while((1<<(logn+1))<=kuan)
    67         logn++;
    68     pre();
    69     for(int i=0;i<=n-kuan;i++)
    70         for(int j=0;j<=m-kuan;j++)
    71             ans=min(ans,ask(i,j));
    72     printf("%d",ans);
    73     return 0;
    74 }
  • 相关阅读:
    cvxpy 示例代码
    Cora 数据集介绍
    图嵌入
    数学建模
    邮件服务器搭建
    windows安装、使用MongoDB
    Django 特殊查询
    软件测试-软件质量
    软件测试-配置管理(7)
    软件测试-缺陷管理(6)
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/7142501.html
Copyright © 2011-2022 走看看