BZOJ1170 Balkan2007 Cipher

来源:互联网 发布:小说小偷源码 编辑:程序博客网 时间:2024/06/01 07:55

这题做的人并不多的样子 , 其实并不是很难啊

提示:

  1. 尝试把矩阵用Hash值表示
  2. 统计一下就好

此题没有详细题解 , 如果有求众数的好方法 , tell me!!

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <string>#include <vector>#include <deque>#include <stack>#include <queue>#include <map>#include <algorithm>#include <cassert>using namespace std;typedef unsigned long long ull;const ull hashNum = 1000007;const int maxn = 1100;__inline int re() { int n; scanf("%d" , &n); return n; }int n , m , x , y;char g[maxn][maxn];ull g1[maxn][maxn];ull Pow[maxn]={1};map<ull, int> dic;int main(int argc, char *argv[]) {    for(int i=1;i<maxn;i++) Pow[i] = Pow[i-1]*hashNum;    n = re(); m = re();    for(int i=0;i<=n;i++) gets(g[i]+1);    x = re(); y = re();    for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) g1[i][j] = g1[i][j-1]*hashNum+g[i][j];    for(int i=1;i<=n;i++) for(int j=m;j>=y;j--) g1[i][j] -= g1[i][j-y]*Pow[y];    for(int i=1;i<=n;i++) for(int j=y;j<=m;j++) g1[i][j] += g1[i-1][j]*hashNum;    for(int i=n;i>=x;i--) for(int j=y;j<=m;j++) g1[i][j] -= g1[i-x][j]*Pow[x];    for(int i=x;i<=n;i++) for(int j=y;j<=m;j++) dic[g1[i][j]]++;    int Max = 0; ull who;    for(map<ull , int>::iterator i = dic.begin();i!=dic.end();i++)         if(Max < i->second) Max = i->second , who = i->first;//  int X = 4 , Y = 3;//  cout<<g1[X+x-1][Y+y-1]<<endl;    printf("%d %d\n" , x , y);    bool first = true;    assert(Max<=1000);    for(int i=x;i<=n;i++) for(int j=y;j<=m;j++) if(who == g1[i][j])    {        if(first)        {            first = false;            for(int ii=i-x+1;ii<=i;ii++)             { for(int jj=j-y+1;jj<=j;jj++) printf("%c" , g[ii][jj]); puts(""); }            printf("%d\n" , Max);        }        printf("%d %d\n" , i-x+1 , j-y+1);    }    return 0;}
0 0