*【牛客 1 - A】矩阵(字符串hash)
生活随笔
收集整理的這篇文章主要介紹了
*【牛客 1 - A】矩阵(字符串hash)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題干:
?
給出一個n * m的矩陣。讓你從中發現一個最大的正方形。使得這樣子的正方形在矩陣中出現了至少兩次。輸出最大正方形的邊長。
輸入描述:
第一行兩個整數n, m代表矩陣的長和寬; 接下來n行,每行m個字符(小寫字母),表示矩陣;輸出描述:
輸出一個整數表示滿足條件的最大正方形的邊長。示例1
輸入
復制
5 10 ljkfghdfas isdfjksiye pgljkijlgp eyisdafdsi lnpglkfkjl輸出
復制
3備注:
對于30%的數據,n,m≤100; 對于100%的數據,n,m≤500;解題報告:
? ?非常惡心的字符串Hash,,琢磨了半天才看明白、、這種前綴的是需要去模數的
AC代碼:
//#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; //}#include<cstdio> #include<algorithm> #define N 510 using namespace std; typedef unsigned long long ll; const ll D1=97,D2=131; int n,m,i,j,l,r,mid,ans,t; char a[N][N]; ll pow1[N],pow2[N],h[N][N],tmp,Hash[N*N]; bool check(int x) {t=0;for(i=1; i<=n; i++) {for(tmp=0,j=1; j<x; j++) tmp=tmp*D1+a[i][j],h[i][j]=0;for(j=x; j<=m; j++) h[i][j]=tmp=tmp*D1-pow1[x]*a[i][j-x]+a[i][j];}for(t=0,i=x; i<=m; i++) {for(tmp=0,j=1; j<x; j++) tmp=tmp*D2+h[j][i];for(j=x; j<=n; j++) Hash[t++]=tmp=tmp*D2-pow2[x]*h[j-x][i]+h[j][i];} sort(Hash,Hash+t);for(i=1; i<t; i++) {if(Hash[i-1]==Hash[i])return 1;}return 0; } int main() {scanf("%d%d",&n,&m);for(i=1; i<=n; i++) {scanf("%s",a[i]+1);for(j=1; j<=m; j++) {a[i][j]-='a';}}l=1,r=min(n,m);pow1[0]=pow2[0]=1;for(i=1; i<=n; i++) pow1[i]=pow1[i-1]*D1;for(i=1; i<=m; i++) pow2[i]=pow2[i-1]*D2;while(l<=r) {mid=(l+r)>>1;if(check(mid)) l=mid+1,ans=mid;else r=mid-1; }printf("%d",ans);return 0; }AC代碼3:(還是這種二維Hash看得懂一點)
#include<bits/stdc++.h> using namespace std; typedef unsigned long long ull; const int maxn=2e6+10; const ull base1=131,base2=233; //base,基數int n, m; char mp[510][510]; ull has[510][510]; ull p1[510], p2[510]; map<ull, int> mmp;void init() {p1[0] = p2[0] = 1;for(int i = 1; i <= 505; i ++){p1[i] = p1[i-1]*base1;p2[i] = p2[i-1]*base2;} }void Hash() {has[0][0] = 0;has[0][1] = 0;has[1][0] = 0;for(int i = 1; i <= n; i ++){for(int j = 1; j <= m; j ++){has[i][j] = has[i][j-1]*base1 + mp[i][j] - 'a';}}for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j ++){has[i][j] = has[i-1][j]*base2 + has[i][j];}} }bool check(int x) {mmp.clear();for(int i = x; i <= n; i ++){for(int j = x; j <= m; j ++){ull k = has[i][j] - has[i-x][j]*p2[x] - has[i][j-x]*p1[x] + has[i-x][j-x]*p1[x]*p2[x];mmp[k] ++;if(mmp[k] >= 2)return true;}}return false; }int main() {init();while(~scanf("%d%d", &n, &m)){for(int i = 1; i <= n; i ++){scanf("%s", mp[i]+1);}Hash();int l = 0, r = 600, ans = 0;while(l <= r){int mid = (l+r)/2;if(check(mid)){l = mid+1;ans = mid;}else{r = mid-1;}}printf("%d\n", ans);}return 0; }?
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的*【牛客 1 - A】矩阵(字符串hash)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 投资者赚翻了?可转债年内平均收益超20%
- 下一篇: 未来几年内,A股有望冲击5000点?要怎