HDU 2146 (Hash)
本来是用字典树的 用了很多种优化竟然都超时 那就只好用hash了 对所有的串进行重构 化为64位整型 然后使用位运算枚举所有K长串
然后用hash存储 使用线性扫描法 还可以优化
代码如下:
#include <iostream>
using namespace std;
typedef struct
{
unsigned __int64 key;
long num;
}Info;
Info hash[68000];
char key[80];
__int64 prime;
long lmax=0;
inline void Dohash(unsigned __int64 key)
{
long pos=key%prime;
if (hash[pos].num==0)
{
hash[pos].num=1;
hash[pos].key=key;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
if (hash[pos].key==key)
{
++hash[pos].num;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
long i,j;
long l;
for (i=1;;++i)
{
for (j=0;j<2;++j)
{
if (!(j&1))
{
l=(pos+i)%prime;
if (hash[l].num==0)
{
hash[l].num=1;
hash[l].key=key;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
if (hash[l].key==key)
{
++hash[l].num;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
}
else
{
l=(pos+prime-i)%prime;
if (hash[l].num==0)
{
hash[l].num=1;
hash[l].key=key;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
if (hash[l].key==key)
{
++hash[l].num;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
}
}
}
}
int main()
{
long N,L,K;
prime=(1<<16)+1;
while (scanf("%ld %ld %ld",&N,&L,&K)!=EOF)
{
lmax=0;
memset(hash,0,sizeof(hash));
unsigned __int64 mask=0;
long i;
long j;
for (i=0;i<K;++i)
{
mask=(mask<<1)+1;
}
for (i=0;i<N;++i)
{
scanf("%s",key);
unsigned __int64 sum=0;
for (j=0;key[j]!='\0';++j)
{
sum=(sum<<1)+(key[j]-'0');
}
long len=L;
while (len-K>=0)
{
unsigned __int64 t=(sum&mask);
sum=sum>>1;
Dohash(t);
--len;
}
}
printf("%ld\n",lmax);
}
return 0;
}
using namespace std;
typedef struct
{
unsigned __int64 key;
long num;
}Info;
Info hash[68000];
char key[80];
__int64 prime;
long lmax=0;
inline void Dohash(unsigned __int64 key)
{
long pos=key%prime;
if (hash[pos].num==0)
{
hash[pos].num=1;
hash[pos].key=key;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
if (hash[pos].key==key)
{
++hash[pos].num;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
long i,j;
long l;
for (i=1;;++i)
{
for (j=0;j<2;++j)
{
if (!(j&1))
{
l=(pos+i)%prime;
if (hash[l].num==0)
{
hash[l].num=1;
hash[l].key=key;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
if (hash[l].key==key)
{
++hash[l].num;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
}
else
{
l=(pos+prime-i)%prime;
if (hash[l].num==0)
{
hash[l].num=1;
hash[l].key=key;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
if (hash[l].key==key)
{
++hash[l].num;
if (hash[pos].num>lmax)
{
lmax=hash[pos].num;
}
return;
}
}
}
}
}
int main()
{
long N,L,K;
prime=(1<<16)+1;
while (scanf("%ld %ld %ld",&N,&L,&K)!=EOF)
{
lmax=0;
memset(hash,0,sizeof(hash));
unsigned __int64 mask=0;
long i;
long j;
for (i=0;i<K;++i)
{
mask=(mask<<1)+1;
}
for (i=0;i<N;++i)
{
scanf("%s",key);
unsigned __int64 sum=0;
for (j=0;key[j]!='\0';++j)
{
sum=(sum<<1)+(key[j]-'0');
}
long len=L;
while (len-K>=0)
{
unsigned __int64 t=(sum&mask);
sum=sum>>1;
Dohash(t);
--len;
}
}
printf("%ld\n",lmax);
}
return 0;
}