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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

编程问答

Matrix(二维hash)

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

題目鏈接

文章目錄

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

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

題目描述

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

示例1
輸入

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

輸出

1 0 1

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

題意:

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

題解

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

其實(shí)本題就是將一維問(wèn)題轉(zhuǎn)化成二維
我們將n * m的矩形中所有大小為a * b的矩形哈希一下并放到哈希表中,然后給出矩陣后,直接O(1)查找就可以了
求矩陣的hash的步驟:
先求出每一行前綴的hash,然后固定矩陣的一邊長(zhǎng)度b,求出長(zhǎng)度為b的邊的hash值,然后從這一行向下延伸a行,求出這a行對(duì)應(yīng)的長(zhǎng)度為b的hash值。當(dāng)長(zhǎ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;//素?cái)?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來(lái)存哈希值,方便后面的判斷是否存在 }}}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ì)查詢是否有這個(gè)數(shù) cout<<"1"<<endl;else cout<<"0"<<endl;}return 0; }

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

總結(jié)

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

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