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