BZOJ 1567: [JSOI2008]Blue Mary的战役地图 Hash+set

来源:互联网 发布:mysql linux安装后在哪 编辑:程序博客网 时间:2024/05/01 22:45

[Submit][Status][Discuss]
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

HINT

样例解释:

子矩阵:
5 6
8 9
为两个地图的最大公共矩阵

约定:
n<=50

解法:先对两个矩阵hash,然后枚举最大长度,从大到小枚举。把第一个矩阵的所有情况插到哈希表中,然后查询第二个矩阵的所有情况,我用的set,也可以用vector然后去二分check。

//BZOJ 1567#include <bits/stdc++.h>using namespace std;typedef long long LL;typedef unsigned long long uLL;const int maxn = 60;const int mod = 999997;const uLL BASE1 = 1333;const uLL BASE2 = 23333;int m;uLL hash1[maxn][maxn], hash2[maxn][maxn];uLL base1[maxn], base2[maxn];set <uLL> s;void input(){    scanf("%d", &m);    for(int i = 1; i <= m; i++){        for(int j = 1; j <= m; j++){            scanf("%lld", &hash1[i][j]);        }    }    for(int i = 1; i <= m; i++){        for(int j = 1; j <= m; j++){            scanf("%d", &hash2[i][j]);        }    }    for(int i = 1; i <= m; i++){        for(int j = 1; j <= m; j++){            hash1[i][j] += hash1[i-1][j]*BASE1;            hash2[i][j] += hash2[i-1][j]*BASE1;        }    }    for(int i = 1; i <= m; i++){        for(int j = 1; j <= m; j++){            hash1[i][j] += hash1[i][j-1]*BASE2;            hash2[i][j] += hash2[i][j-1]*BASE2;        }    }    base1[0] = base2[0] = 1;    for(int i = 1; i <= m; i++){        base1[i] = base1[i-1]*BASE1;        base2[i] = base2[i-1]*BASE2;    }}void work(){    s.clear();    int ans, flag  = 0;    for(ans = m; ans; ans--){        for(int i = ans; i <= m; i++){            for(int j = ans; j <= m; j++){                uLL h = hash1[i][j];                h -= hash1[i-ans][j]*base1[ans];                h -= hash1[i][j-ans]*base2[ans];                h += hash1[i-ans][j-ans]*base1[ans]*base2[ans];                //h %= mod;                s.insert(h);            }        }        for(int i = ans; i <= m; i++){            for(int j = ans; j <= m; j++){                uLL h = hash2[i][j];                h -= hash2[i-ans][j]*base1[ans];                h -= hash2[i][j-ans]*base2[ans];                h += hash2[i-ans][j-ans]*base1[ans]*base2[ans];                //h %= mod;                if(s.find(h) != s.end()){                    flag = 1;                    break;                }            }            if(flag) break;        }        if(flag) break;    }    if(flag) cout << ans << endl;    else cout << 0 << endl;}void output(){}int main(){    input();    work();}
0 0
原创粉丝点击