zoukankan      html  css  js  c++  java
  • hdu 6046 hash

    题:

      OwO http://acm.hdu.edu.cn/showproblem.php?pid=6046

      (2017 Multi-University Training Contest - Team 2 - 1002)  

    解:

      设A矩阵为1e3*1e3的那个矩阵,另一个叫B矩阵

      首先对A矩阵进行预处理,每一行中的每一个点的哈希值为这个点和其右边63个点的组合值(总计64个点)(如果右边没63个点了那就不做了),放入hashmap中

      然后对B矩阵进行扫描。

      想象把很多个A矩阵铺在B矩阵上面,使A矩阵有预处理的部分铺满B矩阵

      那么对B矩阵每1000行枚举一行,每900列枚举一列,则这些行列的交叉点钟必然有一个点存在于A矩阵中。

      由这个点的哈希值(就是前文说的该点对应的64个点的组合值)那么找出这个点,并且由hashmap得知这个点在A矩阵中的位置,就可以得知A矩阵在B矩阵中的具体位置。

      (思路来源为某其他博客)

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    typedef unsigned long long ll;
    
    const ll hashM=1200044;
    const ll hashmod=1442441;
    ll hashval[hashM],hashtol;
    int hashnxt[hashM],hashpos[hashM],hashid[hashmod];
    
    void hashInit()
    {
    	hashtol=0;
    	memset(hashid,0,sizeof(hashid));
    }
    
    void hashInsert(ll val,int pos)
    {
    	int tmp=val%hashmod;
    	hashtol++;
    	hashval[hashtol]=val;
    	hashpos[hashtol]=pos;
    	hashnxt[hashtol]=hashid[tmp];
    	hashid[tmp]=hashtol;
    }
    
    int hashFindpos(ll val)
    {
    	int tmp=val%hashmod;
    	for(int i=hashid[tmp];i;i=hashnxt[i])
    		if(hashval[i]==val)
    			return hashpos[i];
    	return -1;
    }
    
    const int N=1000;
    const int M=1044;
    const int bas=1024;
    const int cps=64;
    char s[M][M];
    
    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;
    }
    
    ll hashtmp[M];
    
    bool check(int x0,int y0)
    {
    	int i,j;
    	for(i=1;i<=N;i++)
    		for(j=1;j<=N;j++)
    			if(f(x0+i-1,y0+j-1)!=(s[i][j]-'0'))
    				return false;
    	return true;
    }
    
    void solve(int cas)
    {
    	int i,j,k,x,y,tmp,x0,y0;
    	ll tmpval;
    	for(i=0;i<1000;i++)	//1000
    		for(j=0;j<=1111;j++)	//900
    		{
    			tmpval=0;
    			for(k=1;k<=cps;k++)
    				tmpval=(tmpval<<1)+f(i*1000+1,j*900+1+k-1);
    			tmp=hashFindpos(tmpval);
    			if(tmp!=-1)
    			{
    				y=tmp%bas; x=(tmp-y)/bas;
    				x0=i*1000+1; y0=j*900+1;
    				x0-=(x-1); y0-=(y-1);
    				if(check(x0,y0))
    				{
    					printf("Case #%d :%d %d
    ",cas,x0,y0);
    					return ;
    				}
    			}
    		}
    }
    
    int main()
    {
    	int T,tmp,i,j,k;
    	ll tmpval;
    	cin>>T;
    	for(int cas=1;cas<=T;cas++)
    	{
    		hashInit();
    		for(i=1;i<=N;i++)
    			scanf("%s",s[i]+1);
    		for(i=1;i<=N;i++)
    		{
    			hashtmp[0]=0;
    			for(j=1;j<=N;j++)
    				hashtmp[j]=(hashtmp[j-1]<<1)+(s[i][j]-'0');
    			for(j=1;j+cps-1<=N;j++)
    				hashInsert(hashtmp[j+cps-1],i*bas+j);
    		}
    		solve(cas);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    java学习笔记07-循环
    java学习笔记06-条件语句
    java学习笔记05-运算符
    java学习笔记04-基本数据类型
    java学习笔记03-基本语法
    java学习笔记02-Eclipse IDE配置
    java学习笔记01-环境配置
    Jmeter学习笔记03-元件作用域及执行顺序
    JMeter学习笔记02-基础介绍
    [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)
  • 原文地址:https://www.cnblogs.com/FxxL/p/7255992.html
Copyright © 2011-2022 走看看