日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Matrix(二维hash)

發(fā)布時間:2023/12/3 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Matrix(二维hash) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接

文章目錄

    • 題目描述
    • 題意:
    • 題解
    • 代碼:

時間限制:C/C++ 1秒,其他語言2秒 空間限制:C/C++ 32768K,其他語言65536K 64bit IO Format: %lld

題目描述

給定一個M行N列的01矩陣(只包含數(shù)字0或1的矩陣),再執(zhí)行Q次詢問,每次詢問給出一個A行B列的01矩陣,求該矩陣是否在原矩陣中出現(xiàn)過。
輸入描述: 第一行四個整數(shù)M,N,A,B。 接下來一個M行N列的01矩陣,數(shù)字之間沒有空格。 接下來一個整數(shù)Q。
接下來Q個A行B列的01矩陣,數(shù)字之間沒有空格。 輸出描述: 對于每個詢問,輸出1表示出現(xiàn)過,0表示沒有。

示例1
輸入

3 3 2 2 111 000 111 3 11 00 11 11 00 11

輸出

1 0 1

備注:
對于40%的數(shù)據(jù),A = 1。
對于80%的數(shù)據(jù),A≤10。
對于100%的數(shù)據(jù),A≤100,M,N≤1000,Q≤1000。

題意:

給你個MN的二維矩陣,然后給你個AB的二維矩陣,問后者是否在前者出現(xiàn)過

題解

毫無疑問用hash
我們先想一個問題:
一個長為L的字符串a(chǎn),問長度為len(len<L)的字符串b在a中出現(xiàn)過嗎?
這個怎么做?
我們可以將a中長度為len的部分求出hash并放進(jìn)哈希表,然后求出b的hash,進(jìn)行比較即可

其實本題就是將一維問題轉(zhuǎn)化成二維
我們將n * m的矩形中所有大小為a * b的矩形哈希一下并放到哈希表中,然后給出矩陣后,直接O(1)查找就可以了
求矩陣的hash的步驟:
先求出每一行前綴的hash,然后固定矩陣的一邊長度b,求出長度為b的邊的hash值,然后從這一行向下延伸a行,求出這a行對應(yīng)的長度為b的hash值。當(dāng)長度大于a后,就將最上面一行刪去,始終保持為 a * b 的矩陣。

代碼:

#include <bits/stdc++.h> using namespace std; const int maxn=1005; typedef unsigned long long ull; ull hash1[maxn][maxn]; ull base[maxn*maxn]; int base1=13; char c[maxn]; ull get(ull hash1[],int l,int r) {return hash1[r]-hash1[l-1]*base[r-l+1]; } int q; int n,m,a,b; int main(){cin>>n>>m>>a>>b;base[0]=1;for(int i=1;i<=n*m;i++) base[i]=base[i-1]*base1;//素數(shù)倍數(shù),用于查詢子串哈希值 for(int i=1;i<=n;i++){scanf("%s",c+1);for(int j=1;j<=m;j++) hash1[i][j]=hash1[i][j-1]*base1+c[j]-'0';//求取每一行前綴哈希值 }unordered_set<ull> s;for(int i=b;i<=m;i++){ull x=0;int l=i-b+1,r=i;for(int j=1;j<=n;j++){x=x*base[b]+get(hash1[j],l,r);// 加上當(dāng)前行的hash值 if(j>a) x-=get(hash1[j-a],l,r)*base[a*b];// 如果超行了,刪去最上面一行 if(j>=a){s.insert(x);//用map來存哈希值,方便后面的判斷是否存在 }}}cin>>q;while(q--){ull x=0;for(int i=0;i<a;i++){scanf("%s",c);for(int j=0;j<b;j++){x=x*base1+c[j]-'0';//將所給的矩陣轉(zhuǎn)化成hash }}if(s.count(x))//利用map性質(zhì)查詢是否有這個數(shù) cout<<"1"<<endl;else cout<<"0"<<endl;}return 0; }

不過這樣做,好像超內(nèi)存了。。。
可以手寫map會好些

總結(jié)

以上是生活随笔為你收集整理的Matrix(二维hash)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。