洛谷P2216

P2216 [HAOI2007] 理想的正方形

绿题T_T
这题思路很好想,就是把二维问题降为一维处理,难点是代码难敲,单调队列的题可能都这样,这块我只能多补强了

点击查看代码
#include<bits/stdc++.h>
using namespace std;

const int L = 1010;
int m[L][L], q[L];
int rowmin[L][L], rowmax[L][L];
int colmin[L][L], colmax[L][L];

int main(){
    int a, b, n; cin >> a >> b >>n;
    int ans = 0x3f3f3f3f;
    for(int i = 1; i <= a; i++) {
        for(int j = 1; j <= b; j++) {
            cin >> m[i][j];
        }
    }

    for(int row = 1; row <= a; row++){
        int h = 0, t = 0;
        for(int i = 0; i <= b; i++) {
            while(h < t && q[h] + n <= i) h++;
            while(h < t && m[row][q[t - 1]] < m[row][i]) t--;
            q[t] = i;
            t++;
            if(i >= n) rowmax[row][i - n + 1] = m[row][q[h]];
        }

        h = 0, t = 0;
        for(int i = 0; i <= b; i++) {
            while(h < t && q[h] + n <= i) h++;
            while(h < t && m[row][q[t - 1]] > m[row][i]) t--;
            q[t] = i;
            t++;
            if(i >= n) rowmin[row][i - n + 1] = m[row][q[h]];
        }
    }
    
    for(int col = 1; col <= b - n + 1; col++){
        int h = 0, t = 0;
        for(int i = 0; i <= a; i++) {
            while(h < t && q[h] + n <= i) h++;
            while(h < t && rowmax[q[t - 1]][col] < rowmax[i][col]) t--;
            q[t] = i;
            t++;
            if(i >= n) colmax[i - n + 1][col] = rowmax[q[h]][col];
        }

        h = 0, t = 0;
        for(int i = 0; i <= b; i++) {
            while(h < t && q[h] + n <= i) h++;
            while(h < t && rowmin[q[t - 1]][col] > rowmin[i][col]) t--;
            q[t] = i;
            t++;
            if(i >= n) colmin[i - n + 1][col] = rowmin[q[h]][col];
        }
    }
    for(int i = 1; i <= a - n + 1; i++) {
        for(int j = 1; j <= b - n + 1; j++) {
            if(colmax[i][j] - colmin[i][j] < ans){
                ans = colmax[i][j] - colmin[i][j];
            }
        }
    }
    cout << ans;
    return 0;
}
posted @ 2025-05-12 17:23  Chuan81  阅读(9)  评论(0)    收藏  举报