BZOJ 1567 JSOI 2008 Blue Mary的战役地图 二维hash

来源:互联网 发布:java中super的用法 编辑:程序博客网 时间:2024/05/23 00:43

题目大意:给出两个m*m的地图,问两个地图的最大子正方形矩阵的边长是多大。


思路:先对两个矩阵hash,然后枚举最大长度,从大到小枚举。把第一个矩阵的所有情况插到哈希表中,然后查询第二个矩阵的所有情况。

记住哈希表中的那些数组一定要开大点。。


CODE:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MAX 60#define RANGE 100100using namespace std;const unsigned long long BASE1 = 1333;const unsigned long long BASE2 = 23333;const int MO = 999997; int m;unsigned long long hash[MAX][MAX],_hash[MAX][MAX];unsigned long long pow1[MAX],pow2[MAX]; struct HashSet{    int head[MO],total;    int next[RANGE];    unsigned long long hash[RANGE];         bool Check(unsigned long long h) {        int x = h % MO;        for(int i = head[x]; i; i = next[i])            if(hash[i] == h)                return true;        return false;    }    void Insert(unsigned long long h) {        int x = h % MO;        next[++total] = head[x];        hash[total] = h;        head[x] = total;    }}set; int main(){    cin >> m;    for(int i = 1; i <= m; ++i)        for(int j = 1; j <= m; ++j)            scanf("%lld",&hash[i][j]);    for(int i = 1; i <= m; ++i)        for(int j = 1; j <= m; ++j)            scanf("%lld",&_hash[i][j]);    for(int i = 1; i <= m; ++i)        for(int j = 1; j <= m; ++j) {            hash[i][j] += hash[i - 1][j] * BASE1;            _hash[i][j] += _hash[i - 1][j] * BASE1;        }    for(int i = 1; i <= m; ++i)        for(int j = 1; j <= m; ++j) {            hash[i][j] += hash[i][j - 1] * BASE2;            _hash[i][j] += _hash[i][j - 1] * BASE2;        }    pow1[0] = pow2[0] = 1;    for(int i = 1; i <= m; ++i)        pow1[i] = pow1[i - 1] * BASE1,pow2[i] = pow2[i - 1] * BASE2;    int ans;    for(ans = m; ans; --ans) {        for(int i = ans; i <= m; ++i)            for(int j = ans; j <= m; ++j) {                unsigned long long h = hash[i][j];                h -= hash[i - ans][j] * pow1[ans];                h -= hash[i][j - ans] * pow2[ans];                h += hash[i - ans][j - ans] * pow1[ans] * pow2[ans];                set.Insert(h);            }        for(int i = ans; i <= m; ++i)            for(int j = ans; j <= m; ++j) {                unsigned long long h = _hash[i][j];                h -= _hash[i - ans][j] * pow1[ans];                h -= _hash[i][j - ans] * pow2[ans];                h += _hash[i - ans][j - ans] * pow1[ans] * pow2[ans];                if(set.Check(h)) {                    cout << ans << endl;                    return 0;                }            }    }    cout << 0 << endl;    return 0;}


0 0
原创粉丝点击