Hdu6046 hash(2017多校第2场)

hash

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 531    Accepted Submission(s): 165


Problem Description
Qscqesze is busy at data cleaning.
One day,he generates a large matrix by Jenkins one-at-a-time hash:
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;
}
Obviously,it's a 1e6*1e6 matrix.The data is at row i column j is f(i,j).Note that i and j are both numbered from 1.
Then he gets some matrices sized 1e3*1e3 from the matrix above.But he forgets their original postion.Can you help him to find them out?You just are asked to tell Qscqesze the left-top corner's postion.
 

Input
The first line is the number of test cases T (T<=3). 
Here come with T cases.Each case is consist of 1000 0/1-strings sized 1000.
For convenience,the sample input is 10*10.And the real testcase is 1e3*1e3.
 

Output
For each test case, output a single line "Case #x :y z", where x is the case number, starting from 1. And y z is the answer.
 

Sample Input
  
  
1 0000011100 0000110011 0111111100 0011110010 0110101010 1001001001 0100111110 1111001010 0011101110 1100110100
 

Sample Output
  
  
Case #1 :123456 234567
 

Source

————————————————————————————————

题意:给出一个1e3*1e3的小矩阵,让你在一个1e6*1e6的矩形内它,并输出左上端点

解题思路:先在1e3*1e3的小矩阵中处理出所有8*8的识别矩阵。然后遍历1e6*1e6的矩阵,遍历时不需要遍历所有点,只需要行之间隔1000,列之间隔1000即可(因为这样里面至少覆盖了一个识别矩阵),然后处理出这个以这个点位左上端点的8*8的小矩阵,然后判断在1e3*1e3的矩阵中能否找到这个矩阵即可


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <math.h>
#include <time.h>
#include <algorithm>
#include <complex>
#include <vector>
#include <stack>
#include <queue>
#include <unordered_map>
#include <set>
using namespace std;

#define LL long long
#define mem(a,b) memset(a,b,sizeof a);

const int inf=0x3f3f3f3f;
const LL llinf=0x3f3f3f3f3f3f3f3f;
const double pi=acos(-1.0);
const double eps=1e-8;
const LL mod=998244353;
const int maxn=2010;

unordered_map<LL,pair<int,int> >mp;
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;
}
char s[1006][1006];
int main()
{
    int T;
    int q=1;
    for(scanf("%d",&T); T--;)
    {
        mp.clear();
        for(int i=0; i<1000; i++)
            scanf("%s",&s[i]);
        for(int i=0; i<=992; i++)
            for(int j=0; j<=992; j++)
            {
                LL x=0;
                for(int k=0; k<8; k++)
                    for(int l=0; l<8; l++)
                    {
                        x<<=1;
                        if(s[i+k][j+l]=='1')
                            x|=1;
                    }
                mp[x]=make_pair(i,j);
            }
        printf("Case #%d :",q++);
        int flag=0;
        for(int i=0; i<1000000; i+=992)
        {
            for(int j=0; j<1000000; j+=992)
            {
                LL x=0;
                for(int k=0; k<8; k++)
                    for(int l=0; l<8; l++)
                    {
                        x<<=1;
                        if(f(i+1+k,j+1+l)==1)
                            x|=1;
                    }
                if(mp.find(x)!=mp.end())
                {
                    printf("%d %d\n",i-mp[x].first+1,j-mp[x].second+1);
                    flag=1;
                    break;
                }
            }
            if(flag)
                break;
        }

    }

    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值