#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define N 100005 using namespace std; char spell[N][85];//储存功能 char magic[N][25];//储存咒语 int num=0; struct node//Hash值对应的数组下标 { int Hash; int l; } key[N],tail[N];//咒语和功能 int cmp(node a,node b) { return a.Hash<b.Hash;//按照Hash排序 } unsigned int BKDRHash(char *str)//Hash算法 { unsigned int seed = 131; unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } void init()//初始化,计算所有串的Hash值 { for(int i=1; i<num; i++) { key[i].Hash=BKDRHash(magic[i]); key[i].l=i; tail[i].Hash=BKDRHash(spell[i]); tail[i].l=i; } sort(key,key+num,cmp);//按照Hash值排序,方便二分查找 sort(tail,tail+num,cmp); // for(int i=0;i<num;i++) // { // cout<<magic[key[i].l]<<endl; // } } int main() { //freopen("in.txt","r",stdin); while(scanf("%s",magic[num])) { if(!strcmp(magic[num],"@END@"))//终止条件 break; getchar();//吞掉空格 gets(spell[num++]);//第二个串 } init();//初始化 int n; scanf("%d",&n); getchar();//吞回车 while(n--)//n次查询 { node tmp; char str[120]; gets(str); if(str[0]=='[')//是咒语 { tmp.Hash=BKDRHash(str);//计算Hsah值 int mid=lower_bound(key,key+num,tmp,cmp)-key;//二分查找位置(如果没找到,返回值为假设这个值存在应该在的位置) if(key[mid].Hash!=tmp.Hash)//比较两者是否相同(是否存在) printf("what?\n"); else printf("%s\n",spell[key[mid].l]);//输出 } else { tmp.Hash=BKDRHash(str); int mid=lower_bound(tail,tail+num,tmp,cmp)-tail; if(tail[mid].Hash!=tmp.Hash) printf("what?\n"); else { int l=strlen(magic[tail[mid].l]);//处理咒语两边的方括号 magic[tail[mid].l][l-1]=0; printf("%s\n",magic[tail[mid].l]+1); } } } return 0; }
hdu 1880 魔咒字典 (hash+二分)
猜你喜欢
转载自blog.csdn.net/l2533636371/article/details/80074379
今日推荐
周排行