题意:
有很多条魔咒,咒语对应效果,效果对应咒语。现在给你一条咒语或者效果,输出其对应的效果或者咒语。如果不存在则输出what?
思路:
将咒语和效果进行读入并HASH成数值以咒语对应效果HASH值和效果对应咒语HASH值打包成结构体,并进行排序。询问将字符串转成HASH值后进行二分即可。
C++代码:
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
const ull maxn = 200010;
const ull mod1 = 1e9+7;
const ull mod2 = 1e9+9;
const ull base1 = 131;
const ull base2 = 233;
char s[150],a[100],b[100];
struct node
{
ull Hash;
char s[100];
friend bool operator< ( const node&a , const node&b )
{
return a.Hash<b.Hash;
}
}data[maxn];
ull GetHash( char s[] )
{
int len = strlen(s);
ull res = 0;
for ( int i=0 ; i<len ; i++ )
res = ( res*base1+(ull)s[i] )%mod1;
return res;
}
int index = 0,n;
int main()
{
while( gets(s) )
{
if ( strcmp( s , "@END@" )==0 ) break;
int len = strlen(s),k = 0,l1 = 0,l2 = 0;
for ( int i=0 ; i<len ; i++ )
{
if ( s[i]==']' )
{
a[l1++] = s[i];
k = 1;
i++;
}
else
{
if ( k )
b[l2++] = s[i];
else
a[l1++] = s[i];
}
}
a[l1] = '\0';
b[l2] = '\0';
data[index].Hash = GetHash(b);
strcpy ( data[index].s , a );
index++;
data[index].Hash = GetHash(a);
strcpy ( data[index].s , b );
index++;
}
sort( data , data+index );
scanf ( "%d" , &n );
getchar();
for ( int i=1 ; i<=n ; i++ )
{
gets(s);
ull t = GetHash(s);
int l=0,r=index-1,mid,ans = -1;
while( l<=r )
{
mid = (l+r)>>1;
if ( data[mid].Hash==t )
{
ans = mid;
break;
}
else if ( data[mid].Hash>t )
{
r = mid-1;
}
else if ( data[mid].Hash<t )
{
l = mid+1;
}
}
if ( ans==-1 )
printf ( "what?\n" );
else
{
if ( data[ans].s[0]=='[' )
{
int tlen = strlen(data[ans].s);
for ( int j=1 ; j<tlen-1 ; j++ )
printf ( "%c" , data[ans].s[j] );
printf ( "\n" );
}
else
printf ( "%s\n" , data[ans].s );
}
}
return 0;
}