http://www.elijahqi.win/archives/2908
Description
给出一个字符矩阵,你要从中找出一个出现次数最多的子矩阵.
Input
第一行给出N,M.代表矩阵的大小. 下面N行M列用来描述矩阵的形态. 再给出X,Y代表子矩阵的大小.
Output
先输出X,Y 再输出你所找到的字符矩阵. 再输出它出现的次数. 再输出它每次出现的位置的左上角坐标.
Sample Input
8 10
qw.aba..f.
wq.bab.ff.
zx.cdc.K.R
c.ababa.es
x.babab.Ed
j.cdcdcaba
yo.k.k.bab
opu..l.cdc
3 3
Sample Output
3 3
aba
bab
cdc
4
1 4
4 3
4 5
6 8
HINT
Source
只要简单的字符串hash即可 注意读入方式需要严格遵照蒟蒻我这样 ..要来数据之后发现这辣鸡读入.. 算出hash值 然后遍历hash值里找一下出现次数最大的 针对每个hash值都开一个vector储存位置在哪里
#include<map>
#include<vector>
#include<queue>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1100
#define g1 11113
#define g2 11117
#define pi make_pair
#define pa pair<int,int>
#define ll unsigned long long
using namespace std;
map<ll,int>::iterator it;
int cnt;map<ll,int> mm1,mm2;
vector<pa> ans[1000010];char s[N][N];
ll hs[N][N],p1[N],p2[N];int n,m,x,y;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
return x*f;
}
int main(){
freopen("bzoj1170.in","r",stdin);
scanf("%d %d\n",&n,&m);p1[0]=p2[0]=1;
for (int i=1;i<=n;++i){
fread(s[i]+1,m+1,1,stdin);
for (int j=1;j<=m;++j)
hs[i][j]=hs[i][j-1]*g1+s[i][j];
for (int j=1;j<=m;++j) hs[i][j]+=hs[i-1][j]*g2;
}for (int i=1;i<=n;++i) p2[i]=p2[i-1]*g2;
for (int i=1;i<=m;++i) p1[i]=p1[i-1]*g1;x=read();y=read();
for (int i=x;i<=n;++i){
for (int j=y;j<=m;++j){ll tmp=0;int id;
tmp+=hs[i][j]+hs[i-x][j-y]*p1[y]*p2[x];
tmp-=hs[i-x][j]*p2[x]+hs[i][j-y]*p1[y];
++mm1[tmp];if (!mm2[tmp]) mm2[tmp]=++cnt,id=cnt;else id=mm2[tmp];
ans[id].push_back(pi(i-x+1,j-y+1));
}
}int mx=0;ll hs1;
for (it=mm1.begin();it!=mm1.end();++it) if(it->second>mx) mx=it->second,hs1=it->first;
printf("%d %d\n",x,y);int id=mm2[hs1],stx=ans[id][0].first,sty=ans[id][0].second;
for (int i=stx;i<stx+x;++i){
for (int j=sty;j<sty+y;++j) putchar(s[i][j]);puts("");
}printf("%d\n",mx);
for (int i=0;i<ans[id].size();++i) printf("%d %d\n",ans[id][i].first,ans[id][i].second);
return 0;
}