zoukankan      html  css  js  c++  java
  • bzoj4165: 矩阵

    Description

    定义和谐矩阵为长不小于 Mina 且宽不小于 Minb 的矩阵,矩阵的权值为整个矩阵内所有数的和。给定一个长为 N
    ,宽为 M 的矩阵 A,求它的所有和谐子矩阵中权值第 K 小的矩阵,并输出它的权值。

    Input

    第 1 行为五个正整数,分别为 N , M , Mina , Minb , K,相邻两个数用一个空格分隔。接下来的 N 行,每行 M
     个用一个空格分隔的数,表示给定的矩阵 A。
    1 <= N,M <=1000, 1 <= Mina <= N, 1 <= Minb <= M,
    1 <= K <= 250000 ,矩阵 A 内每个数均为不超过 3000 的非负整数

    Output

    仅一行,一个数,表示第 K 小矩阵的权值。如果第 K 小矩阵不存在,输出-1。

    由于矩阵内整数非负,若子矩阵P包含子矩阵Q则sum(P)>sum(Q)

    最小的子矩阵长宽一定为(Mina , Minb),从最小的矩阵开始向外bfs,每个子矩阵可以向上/下/左/右扩展一行/列,注意判重

    用堆维护搜索顺序,散列表维护一个状态是否出现过,第k个出堆的子矩阵为答案

    #include<cstdio>
    #include<cstdlib>
    #include<queue>
    const int P=2097152,R=10000000;
    char buf[R],*ptr=buf-1;
    inline int _int(){
        int x=0,c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    int n,m,n1,m1,k;
    unsigned int s[1024][1024],rnd[1024][1024];
    struct data{
        unsigned int x1,y1,x2,y2,sum;
        data(){}
        inline data(int _x1,int _y1,int _x2,int _y2):x1(_x1),y1(_y1),x2(_x2),y2(_y2){
            sum=s[x2][y2]+s[x1][y1]-s[x2][y1]-s[x1][y2];
        }
    }w;
    inline bool operator<(const data&a,const data&b){
        return a.sum>b.sum;
    }
    inline bool operator==(const data&a,const data&b){
        return a.x1==b.x1&&a.y1==b.y1&&a.y2==b.y2&&a.x2==b.x2;
    }
    std::priority_queue<data>q;
    bool ins(data x){
        static data xs[P];
        static bool ed[P];
        int w=rnd[x.x1][x.y1]^rnd[x.x2][x.y2];
        while(ed[w]){
            if(xs[w]==x)return 0;
            w+=12347;
            if(w>=P)w-=P;
        }
        xs[w]=x;ed[w]=1;
        return 1;
    }
    inline void push(data x){
        if(ins(x))q.push(x);
    }
    int main(){
        fread(buf,1,R-4,stdin);
        srand(1844677);
        n=_int();m=_int();n1=_int();m1=_int();k=_int();
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)s[i][j]=_int()+s[i][j-1],rnd[i][j]=(rand()^rand()<<10)&2097151;
        for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)s[i][j]+=s[i-1][j];
        for(int i=n1;i<=n;i++)for(int j=m1;j<=m;j++)push(data(i-n1,j-m1,i,j));
        for(int i=0;i<k;i++){
            if(q.empty()){
                puts("-1");
                return 0;
            }
            w=q.top();q.pop();
            if(w.x1)push(data(w.x1-1,w.y1,w.x2,w.y2));
            if(w.y1)push(data(w.x1,w.y1-1,w.x2,w.y2));
            if(w.x2!=n)push(data(w.x1,w.y1,w.x2+1,w.y2));
            if(w.y2!=m)push(data(w.x1,w.y1,w.x2,w.y2+1));
        }
        printf("%u
    ",w.sum);
        return 0;
    }
  • 相关阅读:
    Oracle,第六周
    JAVA创建对象的几种方式
    深拷贝和浅拷贝
    Facade
    Adapter
    低谷过去了
    Oracle,第五周
    Command
    Singleton
    mybatis自动生成mapping和实体
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5657872.html
Copyright © 2011-2022 走看看