BZOJ 1567: [JSOI2008]Blue Mary的战役地图 矩阵二维hash

1567: [JSOI2008]Blue Mary的战役地图


Description

Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏。她正在设法寻找更多的战役地图以进一步提高自己的水平。 由于Blue Mary的技术已经达到了一定的高度,因此,对于用同一种打法能够通过的战役地图,她只需要玩一张,她就能了解这一类战役的打法,然后她就没有兴趣再玩儿这一类地图了。而网上流传的地图有很多都是属于同一种打法,因此Blue Mary需要你写一个程序,来帮助她判断哪些地图是属于同一类的。 具体来说,Blue Mary已经将战役地图编码为n*n的矩阵,矩阵的每个格子里面是一个32位(有符号)正整数。对于两个矩阵,他们的相似程度定义为他们的最大公共正方形矩阵的边长。两个矩阵的相似程度越大,这两张战役地图就越有可能是属于同一类的。

Input

第一行包含一个正整数n。 以下n行,每行包含n个正整数,表示第一张战役地图的代表矩阵。 再以下n行,每行包含n个正整数,表示第二张战役地图的代表矩阵。

Output

仅包含一行。这一行仅有一个正整数,表示这两个矩阵的相似程度。

Sample Input

3
1 2 3
4 5 6
7 8 9
5 6 7
8 9 1
2 3 4

Sample Output

2
 
 
 
题解:
  二维hash
 
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
typedef unsigned long long ULL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 2e5+10, M = 1e3+20,inf = 2e9;

/*inline LL read()
{
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}*/
const ULL mod1 = 133700613937LL, mod2 = 10031LL;
ULL sqr1[60],sqr2[60],ahas[60][60],bhas[60][60];

LL a[60][60],b[60][60];
int n;
map<ULL, int > mp;
int ok(int w) {
    mp.clear();
    for(int i = w; i <= n; ++i) {
        for(int j = w; j <= n; ++j)
        {
            mp[sqr1[n - i + 1] * sqr2[n - j + 1] * (ahas[i][j] + ahas[i-w][j-w] - ahas[i-w][j] - ahas[i][j-w])] = 1;
        }
    }
    for(int i = w; i <= n; ++i) {
        for(int j = w; j <= n; ++j)
        {
            if(mp[sqr1[n - i + 1] * sqr2[n - j + 1] * (bhas[i][j] + bhas[i-w][j-w] - bhas[i-w][j] - bhas[i][j-w])])
                return 1;
        }
    }
    return 0;
}
int main() {
    sqr1[0] = 1LL;sqr2[0] = 1LL;
    for(int i = 1; i <= 59; ++i)
        sqr1[i] = sqr1[i-1] * mod1,
        sqr2[i] = sqr2[i-1] * mod2;
    scanf("%d",&n);
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            scanf("%lld",&a[i][j]),
            ahas[i][j] = sqr1[i] * sqr2[j] * a[i][j],
            ahas[i][j] += ahas[i][j-1] + ahas[i-1][j] - ahas[i-1][j-1];
    for(int i = 1; i <= n; ++i)
        for(int j = 1; j <= n; ++j)
            scanf("%lld",&b[i][j]),
            bhas[i][j] = sqr1[i] * sqr2[j] * b[i][j],
            bhas[i][j] += bhas[i][j-1] + bhas[i-1][j] - bhas[i-1][j-1];
    int ans = 0;
    for(int w = n; w >= 1; w--) {
        if(ok(w)) {
            printf("%d\n",w);
            return 0;
        }
    }
    printf("0\n");
    return 0;
}

 

posted @ 2017-08-04 14:22  meekyan  阅读(181)  评论(0编辑  收藏  举报