HDU 6046 hash(鸽巢原理+unordered_map)

来源:互联网 发布:淘宝童装店铺排名 编辑:程序博客网 时间:2024/05/18 18:03

Description
给出一个hash函数,用该hash函数可以得到一个1e6*1e6的01矩阵,现在要在这个大矩阵中找到一个1e3*1e3的小矩阵,问该小矩阵的左上角元素在大矩阵中所处位置
Input
第一行一整数T表示用例组数,每组用例输入一个1e3*1e3的01矩阵(T<=3)
Output
输出小矩阵的左上角元素在大矩阵中所处位置
Sample Input
1
0000011100
0000110011
0111111100
0011110010
0110101010
1001001001
0100111110
1111001010
0011101110
1100110100
Sample Output
Case #1 :123456 234567
Solution
从大矩阵左上角开始每隔1000-16行和1000-16列选出若干8*8小矩阵,那么由鸽巢原理至少有一个这种小矩阵会出现在所给的1000*1000的矩阵中,把这些8*8的小矩阵看作一个64位数的二进制表示,用unordered_map存下这些值与其位置之间的关系,然后枚举所给1000*1000矩阵中所有8*8矩阵,只要找到一个即固定了这个矩阵在大矩阵中的位置
Code

#include<cstdio>#include<map>#include<unordered_map>using namespace std;typedef long long ll;typedef pair<int,int>P;const int maxn=1001;unordered_map<ll,P>M;char s[maxn][maxn];inline unsigned sfr(unsigned h, unsigned x){    return h>>x;}int f(ll i, ll j){    ll w=i*1000000ll+j;    int h=0;    for(int k=0;k<5;k++)    {        h+=(int)((w>>(8*k))&255);        h+=(h<<10);        h^=sfr(h,6);    }    h+= h<<3;    h^=sfr(h,11);    h+=h<<15;    return sfr(h,27)&1;}int Case=1,T;int main(){    scanf("%d",&T);    while(T--)    {        for(int i=1;i<=1000;i++)scanf("%s",s[i]+1);        M.clear();        for(int i=1;i<=992;i++)            for(int j=1;j<=992;j++)            {                ll temp=0;                for(int k=0;k<8;k++)                    for(int l=0;l<8;l++)                    {                        temp<<=1;                        if(s[i+k][j+l]=='1')temp|=1;                    }                M[temp]=P(i,j);            }        int gg=1;        for(int i=1;i<=1e6&&gg;i+=984)            for(int j=1;j<=1e6&&gg;j+=984)            {                ll temp=0;                for(int k=0;k<8;k++)                    for(int l=0;l<8;l++)                    {                        temp<<=1;                        if(f(i+k,j+l))temp|=1;                    }                if(M.find(temp)!=M.end())                {                    P ans=M[temp];                    gg=0;                    printf("Case #%d :%d %d\n",Case++,i-ans.first+1,j-ans.second+1);                }            }    }}