uva10887

来源:互联网 发布:linux wpa supplicant 编辑:程序博客网 时间:2024/06/05 01:15
hash实在无爱。。。。。看的云里雾里的。。。。。。。
思路:
1. 计算出字符串的三个哈希值(一个用来确定位置,另外两个用来校验)
2. 察看哈希表中的这个位置
3. 哈希表中这个位置为空吗?如果为空,则肯定该字符串不存在,返回
4. 如果存在,则检查其他两个哈希值是否也匹配,如果匹配,则表示找到了该字符串,返回
5. 移到下一个位置,如果已经越界,则表示没有找到,返回
6. 看看是不是又回到了原来的位置,如果是,则返回没找到
7. 回到3 
三个hash值重复的可能性大约就很小很小了吧。。。。
#include <iostream>#include <string>#include <cstdio>#include <cstring>using namespace std;int cryptTable[0x500];void prepareCryptTable(){    unsigned long seed = 0x00100001, index1 = 0, index2 = 0, i;    for( index1 = 0; index1 < 0x100; index1++ )    {        for( index2 = index1, i = 0; i < 5; i++, index2 += 0x100 )        {            unsigned long temp1, temp2;            seed = (seed * 125 + 3) % 0x2AAAAB;            temp1 = (seed & 0xFFFF) << 0x10;            seed = (seed * 125 + 3) % 0x2AAAAB;            temp2 = (seed & 0xFFFF);            cryptTable[index2] = ( temp1 | temp2 );       }   }}unsigned long HashString( const char *lpszFileName, unsigned long dwHashType ){    unsigned char *key  = (unsigned char *)lpszFileName;    unsigned long seed1 = 0x7FED7FED;    unsigned long seed2 = 0xEEEEEEEE;    int ch;    while( *key != 0 )    {        ch = toupper(*key++);        seed1 = cryptTable[(dwHashType << 8) + ch] ^ (seed1 + seed2);        seed2 = ch + seed1 + seed2 + (seed2 << 5) + 3;    }    return seed1;}bool vis [10000000];int num2 [10000000];int num3 [10000000];int main(){    prepareCryptTable();    int T,t=0;    cin>>T;    while(T--)    {        memset(vis,false,sizeof(vis));        memset(num2,0,sizeof(num2));        memset(num3,0,sizeof(num3));        int num_a,num_b;        cin>>num_a>>num_b;        getchar();        string a[num_a],b[num_b];        for(int i=0;i<num_a;i++)            getline(cin,a[i]);        for(int j=0;j<num_b;j++)            getline(cin,b[j]);        int sum=0;        for(int i=0;i<num_a;i++)            for(int j=0;j<num_b;j++)        {            string s=a[i]+b[j];            unsigned long n1=HashString(s.c_str(),0)%10000000;            unsigned long n2=HashString(s.c_str(),1)%10000000;            unsigned long n3=HashString(s.c_str(),2)%10000000;            if(vis[n1])            {                if(n2==num2[n1]&&n3==num3[n1])                    continue;                else                {                    bool exist=false;                    int k;                    for(k=n1+1;k<10000000&&vis[k]&&k!=n1;k++)                        if(n2==num2[k]&&n3==num3[k])                        {                            exist=true;                            break;                        }                        if(exist)                            continue;                        else                            vis[k]=true,num2[k]=n2,num3[k]=n3,sum+=1;                }            }            else                vis[n1]=true,num2[n1]=n2,num3[n1]=n3,sum+=1;        }         cout << "Case " << ++t << ": " << sum << endl;    }}


0 0