hash表

哈希表(散列表)的基本原理:
使用一个 下标范围比较大的数组 来存储元素,一般通过设计一个函数(哈希函数,即散列函数),使得每个元素的关键字都与一个函数值(即数组下标)相对应,然后用该数组单元来存储对应元素。
1,整数hash
例题:
hdu 1425 sort
排序可能会超时
在输入的过程中排好序,最大复杂度 2 * 1000000
# include <cstdio>
# include <cstring>
# include <algorithm>
using  namespace  std;
int  a[ 1000010 ];
int  main()
{
     int  n,m;
     while (scanf( "%d%d" ,&n,&m)!=EOF)
     {
         int  x;
         memset(a, 0 ,sizeof(a));
         int  maxn= 0 ;
         for ( int  i= 0 ;i<n;i++)
         {
             scanf( "%d" ,&x);
             x=x+ 500000 ;
             maxn=max(maxn,x);
             a[x]= 1 ;
         }
         int  ans= 0 ;
         for ( int  i=maxn;i>= 0 ;i--)
         {
             if (a[i])
             {
                 ans++;
                 printf( "%d" ,i- 500000 );
                 if (ans!=m) printf( " " );
                     if (ans==m)  break ;
             }
         }
         printf( "\n" );
     }
     return  0 ;
}

hdu 1496 Equations

利用hash表将O(n^3)的复杂度降为2*O(n^2)


# include <cstdio>
# include <cstring>
# include <algorithm>
# include <cmath>
using  namespace  std;
int  p[ 102 ];
int  hash[ 2000010 ];
int  main()
{
     for ( int  i= 1 ;i<= 100 ;i++)
         p[i]=i*i;
     int  a,b,c,d;
     while (scanf( "%d%d%d%d" ,&a,&b,&c,&d)!=EOF)
     {
         if (a< 0 &&b< 0 &&c< 0 &&d< 0 ||a> 0 &&b> 0 &&c> 0 &&d> 0 )
         {
             printf( "0\n" );
             continue ;
         }
         memset(hash, 0 ,sizeof(hash));
         for ( int  i= 1 ;i<= 100 ;i++)
         {
             for ( int  j= 1 ;j<= 100 ;j++)
                 hash[a*p[i]+b*p[j]+ 1000000 ]++;
         }
         int  cnt= 0 ;
         for ( int  i= 1 ;i<= 100 ;i++)
         {
             for ( int  j= 1 ;j<= 100 ;j++)
             {
                 cnt+=hash[-(c*p[i]+d*p[j])+ 1000000 ];
             }
         }
         printf( "%d\n" , 16 *cnt);
     }
     return  0 ;
}

2,字符串hash

常见hash处理:

                         如果字符串中可能出现的字符有k个,则可以将字符串对应到k进制数
                         例如:只含有小写字母的字符串:hki~(h-'a'+1)*26^2+(k-'a'+1)*26^1+i-'a'+1;//+1是为了解决冲突因为如果a~0,则ab=b。。。产生冲突。。
                         含k个字符为什么要对应到k进制数??原因是,只有这样才能表示表示所有的字符。。就是说每个字符才能对应一个数字。
                         在有些情况下可以直接用字符串当键值,当字符串的ascii码一定不相等的时候。例如hdu1228,hash["zero"]=0。。。。。。

ELF算法模板:

inline int ELFhash(char *key)
{
unsigned long h = 0;
unsigned long g;
while( *key )
{
h =( h<< 4) + *key++;
g = h & 0xf0000000L;
if( g ) h ^= g >> 24;
h &= ~g;
}
return h;
}

其他hash算法见:http://acm.hdu.edu.cn/forum/read.php?tid=7329

例题:

hdu 1800  Flying to the Mars//对着模板写的。。。对这个算法不懂

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 7003
int hash[MAXN];
int count1[MAXN];
using namespace std;
int maxn;
int ELFhash(char *s)
{
unsigned long h=0;
unsigned long g;
while(*s)
{
h=(h<<4)+*s++;
g=h&0xf0000000L;
if(g) h^=g>>24;
h&=~g;
}
return h;
}
void getsolve(char *s)
{
while(*s=='0') s++;
int k=ELFhash(s);
int t=k%MAXN;
while(hash[t]!=k&&hash[t]!=-1)
t=(t+10)%MAXN;
if(hash[t]==-1) count1[t]=1,hash[t]=k;
else if(++count1[t]>maxn) maxn=count1[t];
}
int main()
{
int n;
char s[40];
while(scanf("%d",&n)!=EOF)
{
maxn=1;
memset(hash,-1,sizeof(hash));
memset(count1,0,sizeof(count1));
while(n--)
{
scanf("%s",s);
   getsolve(s);
}
printf("%d\n",maxn);
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值