1. 程式人生 > 其它 >前端的一些小技巧

前端的一些小技巧

原題連結

在二維上運用單調佇列,我們可以想象在矩陣上移動滑動視窗,以左上角為起點,在在視窗內部我們對每一行求最值,再對每一列求最值,那麼左上角的元素一定是最值,只需要將每個滑動視窗最值儲存即可

沒什麼坑,有思路很快就能做出來

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1010;
 4 int c[N][N],tmpx[N][N],tmpX[N][N],q[N],Q[N];//求每一行n範圍的最大值、最小值再對其求每一列的最值 
 5 int main()//以左上角座標為基準 
 6 {
 7 //    freopen("in.txt","r",stdin);
8 int a,b,n,ans = INT_MAX; 9 scanf("%d%d%d",&a,&b,&n); 10 for(int i=1;i<=a;i++) 11 for(int j=1;j<=b;j++) 12 scanf("%d",&c[i][j]); 13 for(int i=1;i<=a;i++){ 14 int tt = -1,TT = -1,hh = 0,HH = 0; 15 for(int j=1;j<=b;j++){ 16
while(hh<=tt&&q[hh]<j-n+1) ++hh; 17 while(HH<=TT&&Q[HH]<j-n+1) ++HH; 18 while(hh<=tt&&c[i][q[tt]]>=c[i][j]) --tt; 19 while(HH<=TT&&c[i][Q[TT]]<=c[i][j]) --TT; 20 q[++tt] = j; Q[++TT] = j;
21 if(j-n+1>0){ 22 tmpx[i][j-n+1] = c[i][q[hh]]; 23 tmpX[i][j-n+1] = c[i][Q[HH]];//對應每一個滑動視窗行的最值 24 } 25 } 26 } 27 for(int j=1;j<=b-n+1;j++){ 28 int tt = -1,TT = -1,hh = 0,HH = 0; 29 for(int i=1;i<=a;i++){ 30 while(hh<=tt&&q[hh]<i-n+1) ++hh; 31 while(HH<=TT&&Q[HH]<i-n+1) ++HH; 32 while(hh<=tt&&tmpx[q[tt]][j]>=tmpx[i][j]) --tt; 33 while(HH<=TT&&tmpX[Q[TT]][j]<=tmpX[i][j]) --TT; 34 q[++tt] = i; Q[++TT] = i; 35 if(i-n+1>0){ 36 tmpx[i-n+1][j] = tmpx[q[hh]][j]; 37 tmpX[i-n+1][j] = tmpX[Q[HH]][j];//對應每一個滑動視窗行的最值 38 } 39 } 40 } 41 for(int i=1;i<=a-n+1;i++) 42 for(int j=1;j<=b-n+1;j++) 43 ans = min(ans,tmpX[i][j]-tmpx[i][j]); 44 printf("%d\n",ans); 45 return 0; 46 }