A - ZJM 与霍格沃兹(必做)
ZJM 为了准备霍格沃兹的期末考试,决心背魔咒词典,一举拿下咒语翻译题
题库格式:[魔咒] 对应功能
背完题库后,ZJM 开始刷题,现共有 N 道题,每道题给出一个字符串,可能是 [魔咒],也可能是对应功能
ZJM 需要识别这个题目给出的是 [魔咒] 还是对应功能,并写出转换的结果,如果在魔咒词典里找不到,输出 “what?”
Input
首先列出魔咒词典中不超过100000条不同的咒语,每条格式为:
[魔咒] 对应功能
其中“魔咒”和“对应功能”分别为长度不超过20和80的字符串,字符串中保证不包含字符“[”和“]”,且“]”和后面的字符串之间有且仅有一个空格。魔咒词典最后一行以“@END@”结束,这一行不属于词典中的词条。
词典之后的一行包含正整数N(<=1000),随后是N个测试用例。每个测试用例占一行,或者给出“[魔咒]”,或者给出“对应功能”。
Output
每个测试用例的输出占一行,输出魔咒对应的功能,或者功能对应的魔咒。如果在词典中查不到,就输出“what?”
Sample Input
[expelliarmus] the disarming charm
[rictusempra] send a jet of silver light to hit the enemy
[tarantallegra] control the movement of one’s legs
[serpensortia] shoot a snake out of the end of one’s wand
[lumos] light the wand
[obliviate] the memory charm
[expecto patronum] send a Patronus to the dementors
[accio] the summoning charm
@END@
4
[lumos]
the summoning charm
[arha]
take me to the sky
Sample Output
light the wand
accio
what?
what?
做法
字符串哈希Bkdr Hash算法
字符串:acd
Hash值:(1*seed^3+5*seed^2+4*seed^1)%mod
这里用unsigned longlong自然溢出以及ASCII码求hash值,字符串比较长,采用倒序求解的方式。
求出魔咒哈希值hash1,功能为hash2.
建立两个map:
map[hash1]=index,a[index]=魔咒
map[hash2]=index,b[index]=英文
查询时先判断是英文还是翻译。
需要注意的是如果用string方式存字符串整体赋值的话,可能会出现上次保存的字符串对本次造成影响的情况(比如上次s=ab,这次本应该s=c,却出现s=cb的情况)。另外注意对变量赋初值。
代码
#include<iostream>
#include<string.h>
#include<string>
#include<map>
using namespace std;
string s;
char a[100009][100];
char b[100009][100];
int main()
{
int index1=0,index2=0;//s1,s2索引
map<unsigned long long, int> mp1,mp2;
while(1)
{
getline(cin,s);
//cout<<s<<endl;
if(s=="@END@")
break;
int i=1,k=0;
char s1[100],s2[100];
for(i;s[i]!=']';i++)
{
s1[k]=s[i];
//cout<<s1[k];
k++;
}
//cout<<k<<endl;
//cout<<s1<<endl;
int len=s.size();
//cout<<len<<endl;
int kk=0;
for(i=i+2;i<len;i++)
{
s2[kk++]=s[i];
}
//cout<<s2<<endl;
//魔咒
unsigned long long temp=0,seed=7;//自然溢出
for(int j=k-1;j>=0;j--)
{
temp=temp+s1[j]*seed;
seed=seed*7;;
//cout<<temp<<endl;
}
mp1.insert(pair<unsigned long long,int>(temp,index1));
//cout<<temp<<endl;
for(int j=0;j<kk;j++)
{
a[index1][j]=s2[j];
}
//a[index1]=s2;
//cout<<a[index1]<<endl;
index1++;
//功能
temp=0;seed=7;
for(int j=kk-1;j>=0;j--)
{
temp=temp+s2[j]*seed;
seed=seed*7;
}
mp2.insert(pair<unsigned long long,int>(temp,index2));
//cout<<temp<<endl;
for(int j=0;j<k;j++)
{
b[index2][j]=s1[j];
}
//b[index2]=s1;
index2++;
}
int n;
cin>>n;
getchar();
while(n--)
{
string tt;
getline(cin,tt);
//cout<<tt<<endl;
int len=tt.size();
//cout<<len<<endl;
map<unsigned long long, int>::iterator iter;
if(tt[0]=='['&&tt[len-1]==']')
{
tt.erase(0,1);
tt.erase(len-2,1);
len=tt.size();
//cout<<tt<<endl;
unsigned long long temp=0,seed=7;
for(int i=len-1;i>=0;i--)
{
temp=temp+tt[i]*seed;
//cout<<temp<<endl;
seed=seed*7;
}
//cout<<temp<<endl;
iter=mp1.find(temp);
if(iter!=mp1.end())
{
int oo=iter->second;
cout<<a[oo]<<endl;
}
else
cout<<"what?"<<endl;
}
else
{
len=tt.size();
unsigned long long temp=0,seed=7;
for(int i=len-1;i>=0;i--)
{
temp=temp+tt[i]*seed;
seed=seed*7;
}
iter=mp2.find(temp);
if(iter!=mp2.end())
{
int oo=iter->second;
cout<<b[oo]<<endl;
}
else
cout<<"what?"<<endl;
}
}
return 0;
}