zoukankan      html  css  js  c++  java
  • 【题解】 bzoj2462: [BeiJing2011]矩阵模板

    题面戳我

    Solution

    • 二维矩阵(hash),判断即可
    • 自己YY了一个方法,(bzoj)T到飞,(一开始还用的三(hash)),交到luogu貌似跑的不慢啊qwq
    • (我是不会告诉你全输出1即可AC)

    Update

    • 我这个代码复杂度是错的(O(n^4))的(我就说怎么卡不进时间,跑的还没暴力快)
    • 正确做法应该是预处理出所有的子矩阵的(Hash)值,然后判重即可,这样就是(O(n^2))的了

    Code

    • 伪·二维(hash)
    // luogu-judger-enable-o2
    //It is coded by ning_mew on 7.24
    #include<bits/stdc++.h>
    #define LL long long
    #define US unsigned
    using namespace std;
    
    const int maxn=1007;
    
    int n,m,A,B,Q=0;
    char ch[maxn][maxn],q[maxn][maxn];
    LL MOD[3]={19260817,20000909,19491001};
    LL Hash[3][maxn][maxn],Pow[3][maxn];
    LL box[3][maxn];
    
    inline void pre(){
        for(US int k=0;k<1;k++){
            Pow[k][0]=1;
            for(US int i=1;i<=n;i++){
                Hash[k][i][0]=0;
                for(US int j=1;j<=m;j++){
                    Hash[k][i][j]=(Hash[k][i][j-1]*2+(ch[i][j]-'0'))%MOD[k];
                    Pow[k][j]=(2*Pow[k][j-1])%MOD[k];
                }
                //cout<<ch[i]+1<<endl;
                //cout<<" pre_hash:"<<k<<' '<<i<<' '<<' '<<Hash[k][i][m]<<endl;
            }
        }
    }
    inline bool check(int x,int y){
        for(US int k=0;k<1;k++){
            for(US int i=x;i<=x+A-1;i++){
                LL sa=((Hash[k][i][y+B-1]-Hash[k][i][y-1]*Pow[k][B])%MOD[k]+MOD[k])%MOD[k];
                LL sb=box[k][i-x+1];
                if(sa!=sb)return false;
            }
        }return true;
    }
    inline void work(){
        //memset(box,0,sizeof(box));
        for(US int k=0;k<1;k++){
            for(US int i=1;i<=A;i++){
                box[k][i]=0;
                for(US int j=1;j<=B;j++){
                    box[k][i]=(box[k][i]*2+(q[i][j]-'0'))%MOD[k];
                }//cout<<" q_hash:"<<k<<' '<<i<<' '<<box[k][i]<<endl;
            }
        }
        for(US int x=1;x<=n-A+1;x++){
            for(US int y=1;y<=m-B+1;y++){
                if(check(x,y)){printf("1
    ");return;}
            }
        }printf("0
    ");return;
    }
    int main(){
        scanf("%d%d%d%d",&n,&m,&A,&B);
        for(US int i=1;i<=n;i++)scanf("%s",ch[i]+1);//,cout<<ch[i]+1<<endl;//cin>>ch[i]+1;
        pre(); scanf("%d",&Q);
        for(US int i=1;i<=Q;i++){
            for(US int j=1;j<=A;j++)scanf("%s",q[j]+1);//,cout<<q[j]+1<<endl;//cin>>q[j]+1;
            work();
        }return 0;	
    }
    

    博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛爆0!!!

  • 相关阅读:
    置换群
    背包问题
    并查集
    链式前向星
    一个简单的金额平均分配函数(C#版)
    EasyUI ComboGrid的绑定,上下键和回车事件,输入条件查询
    Oracle表解锁语句
    如何将两个json合并成一个
    textbox只能输入数字或中文的常用正则表达式和验证方法
    C#注册表的读,写,删除,查找
  • 原文地址:https://www.cnblogs.com/Ning-Mew/p/9361812.html
Copyright © 2011-2022 走看看