[BZOJ1047][HAOI2007]理想的正方形
阿新 • • 發佈:2017-09-20
ref ble ans mit 組成 i++ ace splay zoj
1047: [HAOI2007]理想的正方形
Time Limit: 10 Sec Memory Limit: 162 MB Submit: 3481 Solved: 1917 [Submit][Status][Discuss]Description
有一個a*b的整數組成的矩陣,現請你從中找出一個n*n的正方形區域,使得該區域所有數中的最大值和最小值 的差最小。
Input
第一行為3個整數,分別表示a,b,n的值第二行至第a+1行每行為b個非負整數,表示矩陣中相應位置上的數。每 行相鄰兩數之間用一空格分隔。 100%的數據2<=a,b<=1000,n<=a,n<=b,n<=1000
Output
僅一個整數,為a*b矩陣中所有“n*n正方形區域中的最大整數和最小整數的差值”的最小值。
Sample Input
5 4 2 單調隊列裸題1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 using namespace std; 8 int a,b,n; 9 int s[1001View Code][1001]; 10 int maxi[1001][1001]; 11 int mini[1001][1001]; 12 int q[1001],w[1001],q1[1001],w1[1001]; 13 int main() 14 { 15 scanf("%d%d%d",&a,&b,&n); 16 for(int i=1;i<=a;i++) 17 for(int j=1;j<=b;j++)scanf("%d",&s[i][j]); 18 int head=0,tail=0,head1=0,tail1=0; 19 for(int i=1;i<=a;i++)20 { 21 head=1,tail=0; 22 head1=1,tail1=0; 23 for(int j=1;j<=b;j++) 24 { 25 while(tail>=head&&s[i][j]>=q[tail]) tail--; 26 q[++tail]=s[i][j];w[tail]=j; 27 while(tail>=head&&w[head]<j-n+1) head++; 28 maxi[i][j]=q[head]; 29 while(tail1>=head1&&s[i][j]<=q1[tail1]) tail1--; 30 q1[++tail1]=s[i][j];w1[tail1]=j; 31 while(tail1>=head1&&w1[head1]<j-n+1) head1++; 32 mini[i][j]=q1[head1]; 33 } 34 } 35 for(int j=1;j<=b;j++) 36 { 37 head=1,tail=0; 38 head1=1,tail1=0; 39 for(int i=1;i<=a;i++) 40 { 41 while(tail>=head&&maxi[i][j]>=q[tail]) tail--; 42 q[++tail]=maxi[i][j];w[tail]=i; 43 while(tail>=head&&w[head]<i-n+1) head++; 44 maxi[i][j]=q[head]; 45 while(tail1>=head1&&mini[i][j]<=q1[tail1]) tail1--; 46 q1[++tail1]=mini[i][j];w1[tail1]=i; 47 while(tail1>=head1&&w1[head1]<i-n+1) head1++; 48 mini[i][j]=q1[head1]; 49 } 50 } 51 int ans=2147483647; 52 for(int i=n;i<=a;i++) 53 for(int j=n;j<=b;j++) ans=min(ans,maxi[i][j]-mini[i][j]); 54 cout<<ans; 55 }
[BZOJ1047][HAOI2007]理想的正方形