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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【牛客 -2A】矩阵(二分,字符串哈希)

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【牛客 -2A】矩阵(二分,字符串哈希) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題干:

給出一個n * m的矩陣。讓你從中發現一個最大的正方形。使得這樣子的正方形在矩陣中出現了至少兩次。輸出最大正方形的邊長。

輸入描述:

第一行兩個整數n, m代表矩陣的長和寬; 接下來n行,每行m個字符(小寫字母),表示矩陣;

輸出描述:

輸出一個整數表示滿足條件的最大正方形的邊長。

?

示例1

輸入

復制

5 10 ljkfghdfas isdfjksiye pgljkijlgp eyisdafdsi lnpglkfkjl

輸出

復制

3

備注:

對于30%的數據,n,m≤100; 對于100%的數據,n,m≤500;

解題報告:

? ?二分一下矩陣的邊長,然后用字符串哈希判斷兩個矩陣是否相同就可以,,網絡上找到一個map的解法,,但是感覺時間復雜度太不穩定,好的時候700ms,差的時候超時,,于是還是以后用多項式哈希吧。。這兩個剛學哈希,,代碼還是不特別美觀、、

AC代碼:

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> #define ll long long #define ull unsigned long long #define pb push_back #define pm make_pair #define fi first #define se second using namespace std; const int MAX = 505; using namespace std; const ll D1=31,D2=131; int n,m; char a[MAX][MAX]; ull pow1[MAX],pow2[MAX],h[MAX][MAX],tmp,tmp2,Hash[MAX*MAX]; bool ok(int x) {memset(h,0,sizeof h);int tot=0;for(int i = 1; i<=n; i++) {ull tmp = 0;for(int j = 1; j<x; j++) h[i][j] = h[i][j-1] * D1 + a[i][j];for(int j = x; j<=m; j++) h[i][j] = h[i][j-1] * D1 + a[i][j] - pow1[x] * a[i][j-x]; // for(int j = 1; j<x; j++) tmp = tmp * D1 + a[i][j]; // for(int j = x; j<=m; j++) h[i][j] = tmp * D1 + a[i][j] - pow1[x] * a[i][j-x] , tmp = h[i][j];}for(int j = x; j<=m; j++) {ull tmp = 0;for(int i = 1; i<x; i++) tmp = tmp*D2 + h[i][j];for(int i = x; i<=n; i++) Hash[++tot] = tmp*D2 + h[i][j] - pow2[x] * h[i-x][j] , tmp = Hash[tot];}sort(Hash+1,Hash+tot+1);for(int i = 1; i<tot; i++) {if(Hash[i] == Hash[i+1]) return 1;}return 0 ; } int main() { // ull qq=1,ww=2; // cout <<qq-ww;scanf("%d%d",&n,&m);for(int i=1; i<=n; i++) {scanf("%s",a[i]+1);for(int j=1; j<=m; j++) {a[i][j]-=('a'-1);}}int l=1,r=min(n,m);int mid = (l+r)>>1;int ans;pow1[0]=pow2[0]=1;for(int i=1; i<=n; i++) pow1[i]=pow1[i-1]*D1;for(int i=1; i<=m; i++) pow2[i]=pow2[i-1]*D2;while(l<=r) {mid=(l+r)>>1;if(ok(mid)) l=mid+1,ans=mid;else r=mid-1; }printf("%d",ans);return 0; }

AC代碼2:(map版)(這個時不時會跑個超時、。。)

#include<cstdio> #include<iostream> #include<algorithm> #include<queue> #include<map> #include<vector> #include<set> #include<string> #include<cmath> #include<cstring> using namespace std; typedef unsigned long long ull; typedef pair<int,int>P; #define maxn 505 int n,m; char s[maxn][maxn]; ull h[maxn][maxn],b[maxn*maxn],base=10007,hhh[maxn][maxn]; inline int ID(int i,int j) {return (i-1)*m+j; } inline bool check(int mid) {map<ull,int>M;for(int x=1; x<=n-mid+1; x++)for(int y=1; y<=m-mid+1; y++) {int xx=x+mid-1,yy=y+mid-1;ull val=(h[xx][yy]-h[xx][y-1]-h[x-1][yy]+h[x-1][y-1])*b[(n-x)*m+m-y];if(M.find(val)!=M.end())return 1;M[val]=1;}return 0; } int main() {scanf("%d%d",&n,&m);for(int i=1; i<=n; i++)scanf("%s",s[i]+1);b[0]=1;for(int i=1; i<=n; i++)for(int j=1; j<=m; j++) {h[i][j]=h[i][j-1]+b[ID(i,j-1)]*(s[i][j]-'a');b[ID(i,j)]=b[ID(i,j-1)]*base;} // for(int j=1; j<=m; j++) // for(int i=1; i<=n; i++) // h[i][j]+=h[i-1][j];int l=0,r=min(n,m),mid,ans=0;while(l<=r) {mid=(l+r)/2;if(check(mid))ans=mid,l=mid+1;else r=mid-1;}printf("%d\n",ans);return 0; }

總結:據syt表示,哈希題目多半帶個log,,這次做題果然是,需要比較,所以需要先排序這樣。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的【牛客 -2A】矩阵(二分,字符串哈希)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。