jquery 中post 、get的同步問題,從外部獲取返回資料
阿新 • • 發佈:2020-11-22
P2216 [HAOI2007]理想的正方形
有一個 \(a×b\) 的整陣列成的矩陣,現請你從中找出一個 \(n×n\) 的正方形區域,使得該區域所有數中的最大值和最小值的差最小。
輸入格式
第一行為三個整數,分別表示 \(a,b,n\) 的值;
第二行至第 \(a+1\) 行每行為 \(b\) 個非負整數,表示矩陣中相應位置上的數。
輸出格式
輸出僅一個整數,為 \(a×b\) 矩陣中所有“\(n×n\) 正方形區域中的最大整數和最小整數的差值”的最小值。
資料範圍
\(2≤a,b≤1000\)
\(n≤a,n≤b,n≤100\)
矩陣中的所有數都不超過 \(10^9\)。
輸入樣例:
5 4 2 1 2 5 6 0 17 16 0 16 17 2 1 2 10 2 1 1 2 2 2
輸出樣例:
1
題解
其實難點就是一維向二維變化的過程,如果是一維,我們可以用線段樹,單調佇列進行維護,
二維呢,其實就是多了\(n\)行,那麼我們可以還是沿用一維的思路
先對\(n\)行分別進行處理,就相當於,把前k個數的最小值,全都摔到\(k\)這一列去,然後,再對算出來的每行 的
資料,進行合併處理,每\(n\)行合併處理一次。這樣,就可以得出一個\(n*n\)的矩陣內的最大值和最小值了
\(row_{min}[i][j]\)表示第\(i\)行,從\(j-k+1\)列到\(j\)列這個區間的最小值
\(row_{max}[i][j]\)表示第\(i\)行,從\(j-k+1\)列到\(j\)
程式碼
#include<bits/stdc++.h> using namespace std; const int N=1010; int w[N][N],row_min[N][N],row_max[N][N]; int q[N]; int n,m,k; void solve(int a[],int len,int ans[],int typede) { int hh=0; int tt=-1; for(int i=1; i<=len; i++) { if(hh<=tt && q[hh]<i-k+1) hh++; while(hh<=tt&&a[q[tt]]*typede<=a[i]*typede) tt--; q[++tt]=i; if(i>=k) ans[i]=a[q[hh]]; } } int main() { cin>>n>>m>>k; for(int i=1; i<=n; i++) for(int j=1; j<=m; j++) cin>>w[i][j]; for(int i=1; i<=n; i++) { solve(w[i],m,row_min[i],-1); solve(w[i],m,row_max[i],1); } int temp[N]; int col_min[N]; int col_max[N]; int ans=0x3f3f3f3f; for(int j=k; j<=m; j++) { for(int i=1;i<=n; i++) temp[i]=row_min[i][j]; solve(temp , n , col_min , -1); for(int i=1; i<=n; i++) temp[i]=row_max[i][j]; solve(temp , n , col_max , 1); for(int i=k; i<=n; i++) { ans=min(ans,col_max[i]-col_min[i]); } } cout<<ans<<endl; return 0; }