题意:
ZJM 为了准备霍格沃兹的期末考试,决心背魔咒词典,一举拿下咒语翻译题。
题库格式:[魔咒] 对应功能。
背完题库后,ZJM 开始刷题,现共有 N 道题,每道题给出一个字符串,可能是 [魔咒],也可能是对应功能。
ZJM 需要识别这个题目给出的是 [魔咒] 还是对应功能,并写出转换的结果,如果在魔咒词典里找不到,输出 “what?”。
首先列出魔咒词典中不超过100000条不同的咒语,每条格式为:
[魔咒] 对应功能。
其中“魔咒”和“对应功能”分别为长度不超过20和80的字符串,字符串中保证不包含字符“[”和“]”,且“]”和后面的字符串之间有且仅有一个空格。魔咒词典最后一行以“@END@”结束,这一行不属于词典中的词条。
词典之后的一行包含正整数N(<=1000),随后是N个测试用例。每个测试用例占一行,或者给出“[魔咒]”,或者给出“对应功能”。
每个测试用例的输出占一行,输出魔咒对应的功能,或者功能对应的魔咒。如果在词典中查不到,就输出“what?”
思路:
这道题卡内存,需要用到字符串哈希算法。用unsigned long long来存储字符串的哈希值,从字符串最后一位到第一位,每一个字符的ACSII值都乘以seed=7的i次方,i从1开始依次增一。这里采用了unsigned long long自然溢出,没有使用mod取模。
读入题库,string s1[]存储功能,string s2[]存储魔咒。然后建立两个map<unsigned long long,int>mp1,mp2,设魔咒哈希值为hash1,功能为hash2,则mp1[hash1]=index,s1[index]=功能;mp2[hash2]=index,s2[index]=魔咒。
查询时先判断是魔咒还是功能,然后在对应的map中查询即可。
总结:
一道字符串哈希题目,设计到了字符串的读入、处理等。读入时字符串内可能有空格,所以要用getline(cin,str)读入,还要记得getchar()吃回车或空格;string的删除是str.erase(index,len),从str[index]开始删除len个字符(包括str[index])。还要注意函数名不能命名为hash,与std::hash冲突,
相同的代码G++会MLE,C++就能A,很是神奇。
代码:
#include <iostream>
#include <map>
#include <cmath>
#include <string>
using namespace std;
#define ull unsigned long long
string s1[100001],s2[100001];
int n;
map<ull,int> mp1,mp2;
const ull seed=7;
ull bkdrHash(string s)
{
ull ret=0,seed1=seed;
for(int i=s.size()-1;i>=0;i--)
{
ret+=(ull)s[i]*seed1;
seed1=seed1*seed;
}
return ret;
}
int main()
{
int index=1;
string str1,str2;
while(cin>>str1)
{
if(str1=="@END@")
break;
getchar(); //吃空格
getline(cin,str2);
str1.erase(0,1);
int len=str1.size();
str1.erase(len-1,1);
s1[index]=str2,s2[index]=str1;
ull hash1=bkdrHash(str1),hash2=bkdrHash(str2);
mp1[hash1]=index,mp2[hash2]=index;
index++;
}
cin>>n;
getchar(); //吃回车
while(n--)
{
string str3;
getline(cin,str3);
if(str3[0]=='[')
{
str3.erase(0,1),str3.erase(str3.size()-1,1);
map<ull,int>::iterator iter=mp1.begin();
iter=mp1.find(bkdrHash(str3));
if(iter!=mp1.end())
cout<<s1[iter->second]<<endl;
else
cout<<"what?"<<endl;
}
else
{
map<ull,int>::iterator iter=mp2.begin();
iter=mp2.find(bkdrHash(str3));
if(iter!=mp2.end())
cout<<s2[iter->second]<<endl;
else
cout<<"what?"<<endl;
}
}
}