zoukankan      html  css  js  c++  java
  • bzoj千题计划215:bzoj1047: [HAOI2007]理想的正方形

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047

    先用单调队列求出每横着n个最大值

    再在里面用单调队列求出每竖着n个的最大值

    这样一个位置就代表了一个n*n矩阵的最大值

    同理求出最小值

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 1001
    
    int num[N][N];
    
    int mx1[N][N],mx2[N][N];
    int mi1[N][N],mi2[N][N];
    
    int q[N],pos[N],h,t;
    
    void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1; c=getchar();  }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    
    int main()
    {
        #ifndef ONLINE_JUDGE
            freopen("data.in","r",stdin);
            freopen("xxy.out","w",stdout);
        #endif
        int a,b,n;
        read(a); read(b); read(n);
        for(int i=1;i<=a;++i)
            for(int j=1;j<=b;++j)
                read(num[i][j]);
        for(int i=1;i<=a;++i)
        {
            h=t=0;
            for(int j=1;j<=b;++j) 
            {
                while(h<t && j-pos[h]+1>n) h++;
                while(h<t && num[i][j]>q[t-1]) t--;
                q[t]=num[i][j];
                pos[t++]=j;
                if(j>=n) mx1[i][j]=q[h];
            }
        }
        for(int j=n;j<=b;++j)
        {
            h=t=0;
            for(int i=1;i<=a;++i)
            {
                while(h<t && i-pos[h]+1>n) h++;
                while(h<t && mx1[i][j]>q[t-1]) t--;
                q[t]=mx1[i][j];
                pos[t++]=i;
                if(i>=n) mx2[i][j]=q[h];
            }
        }
        for(int i=1;i<=a;++i)
        {
            h=t=0;
            for(int j=1;j<=b;++j) 
            {
                while(h<t && j-pos[h]+1>n) h++;
                while(h<t && num[i][j]<q[t-1]) t--;
                q[t]=num[i][j];
                pos[t++]=j;
                if(j>=n) mi1[i][j]=q[h];
            }
        }
        for(int j=n;j<=b;++j)
        {
            h=t=0;
            for(int i=1;i<=a;++i)
            {
                while(h<t && i-pos[h]+1>n) h++;
                while(h<t && mi1[i][j]<q[t-1]) t--;
                q[t]=mi1[i][j];
                pos[t++]=i;
                if(i>=n) mi2[i][j]=q[h];
            }
        }
        int ans=2e9;
        for(int i=n;i<=a;++i)
            for(int j=n;j<=b;++j)
                ans=min(ans,mx2[i][j]-mi2[i][j]);
        printf("%d",ans);
    }
    AC
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 1001
    
    int num[N][N];
    
    int mx[N][N];
    int mi[N][N];
    
    int q[N],pos[N],h,t;
    
    void read(int &x)
    {
        x=0; int f=1; char c=getchar();
        while(!isdigit(c)) { if(c=='-') f=-1; c=getchar();  }
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
        x*=f;
    }
    
    int main()
    {
        freopen("data.in","r",stdin);
        freopen("std.out","w",stdout);
        int a,b,n;
        read(a); read(b); read(n);
        for(int i=1;i<=a;++i)
            for(int j=1;j<=b;++j)
                read(num[i][j]);
        int ans=1e9;
        for(int i=1;i+n-1<=a;++i)
            for(int j=1;j+n-1<=b;++j)
            {
                int I=i+n-1;
                int J=j+n-1;
                int p=1e9,q=-1e9;
                for(int k=i;k<=I;++k)
                    for(int l=j;l<=J;++l)
                        p=min(p,num[k][l]),q=max(q,num[k][l]);
                ans=min(ans,q-p);
            }
        printf("%d",ans);
    }
    force
    #include<cmath>
    #include<cstdlib>
    #include<cstdio>
    #include<ctime>
    
    using namespace std;
    
    int main()
    {
        freopen("data.in","w",stdout);
        srand(time(0)+20001024);
        int a=50,b=60;
        int n=rand()%10+1;
        printf("%d %d %d
    ",a,b,n);
        for(int i=1;i<=a;++i)
        {
            for(int j=1;j<=b;++j) printf("%d ",rand());
            printf("
    ");
        }
    }
    maker

    1047: [HAOI2007]理想的正方形

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 3791  Solved: 2095
    [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 2 5 6
    0 17 16 0
    16 17 2 1
    2 10 2 1
    1 2 2 2

    Sample Output

    1
  • 相关阅读:
    java_day12_jdk1.8新特性
    IT修养-基础篇
    selenium之 chromedriver与chrome版本映射表(更新至v2.31)
    selenium--定位--CSS
    敏捷测试--之scrum--原理
    敏捷测试和瀑布测试的关联
    bugfree安装
    Linux
    mysql--命令行创建数据库
    软件测试流程
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8384992.html
Copyright © 2011-2022 走看看