HDU 1880 魔咒词典(字符串哈希)
2015-11-14 15:56
405 查看
题目链接
给你一部魔咒词典。当哈利听到一个魔咒时,你的程序必须告诉他那个魔咒的功能;当哈利需要某个功能但不知道该用什么魔咒时,你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中,就输出“what?”
[魔咒] 对应功能
其中“魔咒”和“对应功能”分别为长度不超过20和80的字符串,字符串中保证不包含字符“[”和“]”,且“]”和后面的字符串之间有且仅有一个空格。词典最后一行以“@END@”结束,这一行不属于词典中的词条。
词典之后的一行包含正整数N(<=1000),随后是N个测试用例。每个测试用例占一行,或者给出“[魔咒]”,或者给出“对应功能”。
题目大意:略。
思路:字符串哈希。
PS:由于这个题目的所有字符串存起来已经有20+MB,对于这个只有32MB内存限制的题目,用map< stirng, string > 只会MLE,于是只能手写hash。
PS2:主要是为了测试一下pb_ds里的hash。使用方法可以参考WC2015的论文《C++的pb_ds库在OI中的应用》。
std::map版本(421MS 31536KB)
cc_hash_table(265MS 32736KB)
gp_hash_table(374MS 31216KB)
Problem Description
哈利波特在魔法学校的必修课之一就是学习魔咒。据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助。给你一部魔咒词典。当哈利听到一个魔咒时,你的程序必须告诉他那个魔咒的功能;当哈利需要某个功能但不知道该用什么魔咒时,你的程序要替他找到相应的魔咒。如果他要的魔咒不在词典中,就输出“what?”
Input
首先列出词典中不超过100000条不同的魔咒词条,每条格式为:[魔咒] 对应功能
其中“魔咒”和“对应功能”分别为长度不超过20和80的字符串,字符串中保证不包含字符“[”和“]”,且“]”和后面的字符串之间有且仅有一个空格。词典最后一行以“@END@”结束,这一行不属于词典中的词条。
词典之后的一行包含正整数N(<=1000),随后是N个测试用例。每个测试用例占一行,或者给出“[魔咒]”,或者给出“对应功能”。
Output
每个测试用例的输出占一行,输出魔咒对应的功能,或者功能对应的魔咒。如果魔咒不在词典中,就输出“what?”题目大意:略。
思路:字符串哈希。
PS:由于这个题目的所有字符串存起来已经有20+MB,对于这个只有32MB内存限制的题目,用map< stirng, string > 只会MLE,于是只能手写hash。
PS2:主要是为了测试一下pb_ds里的hash。使用方法可以参考WC2015的论文《C++的pb_ds库在OI中的应用》。
std::map版本(421MS 31536KB)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <string> #include <map> typedef long long LL; const int MAXN = 108; std::map<int, int> dict_forward, dict_backward; std::string a[100000], b[100000]; char str1[MAXN], str2[MAXN]; std::string tmp1, tmp2; int n; int gethash(const std::string &str) { LL res = 0; for(char c : str) res = (res * 131 + c) % 1000000007; return res; } void myfind(const std::string &s, std::map<int, int> &dict, std::string arr[]) { auto it = dict.find(gethash(s)); if(it != dict.end()) { std::cout<<arr[it->second]<<std::endl; } else { puts("what?"); } } int main() { int cnt = 0; while(gets(str1) && strcmp(str1, "@END@") != 0) { int pos = strchr(str1, ']') - str1; a[cnt] = std::string(str1 + 1, pos - 1); b[cnt] = std::string(str1 + pos + 2); dict_forward[gethash(a[cnt])] = cnt; dict_backward[gethash(b[cnt])] = cnt; cnt++; } scanf("%d", &n); getchar(); for(int i = 0; i < n; ++i) { gets(str1); if(*str1 == '[') { tmp1 = std::string(str1 + 1, strlen(str1) - 2); myfind(tmp1, dict_forward, b); } else { myfind(str1, dict_backward, a); } } }
cc_hash_table(265MS 32736KB)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <string> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/hash_policy.hpp> typedef long long LL; const int MAXN = 108; __gnu_pbds::cc_hash_table<int, int> dict_forward, dict_backward; std::string a[100000], b[100000]; char str[MAXN]; std::string tmp1, tmp2; int n; int gethash(const std::string &str) { LL res = 0; for(char c : str) res = (res * 131 + c) % 1000000007; return res; } void myfind(const std::string &s, __gnu_pbds::cc_hash_table<int, int> &dict, std::string arr[]) { auto it = dict.find(gethash(s)); if(it != dict.end()) { std::cout<<arr[it->second]<<std::endl; } else { puts("what?"); } } int main() { int cnt = 0; while(gets(str) && strcmp(str, "@END@") != 0) { int pos = strchr(str, ']') - str; a[cnt] = std::string(str + 1, pos - 1); b[cnt] = std::string(str + pos + 2); dict_forward[gethash(a[cnt])] = cnt; dict_backward[gethash(b[cnt])] = cnt; cnt++; } scanf("%d", &n); getchar(); for(int i = 0; i < n; ++i) { gets(str); if(*str == '[') { tmp1 = std::string(str + 1, strlen(str) - 2); myfind(tmp1, dict_forward, b); } else { myfind(str, dict_backward, a); } } }
gp_hash_table(374MS 31216KB)
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <string> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/hash_policy.hpp> typedef long long LL; const int MAXN = 108; __gnu_pbds::gp_hash_table<int, int> dict_forward, dict_backward; std::string a[100000], b[100000]; char str[MAXN]; std::string tmp1, tmp2; int n; int gethash(const std::string &str) { LL res = 0; for(char c : str) res = (res * 131 + c) % 1000000007; return res; } void myfind(const std::string &s, __gnu_pbds::gp_hash_table<int, int> &dict, std::string arr[]) { auto it = dict.find(gethash(s)); if(it != dict.end()) { std::cout<<arr[it->second]<<std::endl; } else { puts("what?"); } } int main() { int cnt = 0; while(gets(str) && strcmp(str, "@END@") != 0) { int pos = strchr(str, ']') - str; a[cnt] = std::string(str + 1, pos - 1); b[cnt] = std::string(str + pos + 2); dict_forward[gethash(a[cnt])] = cnt; dict_backward[gethash(b[cnt])] = cnt; cnt++; } scanf("%d", &n); getchar(); for(int i = 0; i < n; ++i) { gets(str); if(*str == '[') { tmp1 = std::string(str + 1, strlen(str) - 2); myfind(tmp1, dict_forward, b); } else { myfind(str, dict_backward, a); } } }
相关文章推荐
- 转载公司同事读书笔记 Effective Refactoring in C++
- Eclipse设置:背景与字体大小和xml文件中字体大小调整
- Android-自定义多TAB悬浮控件实现蘑菇街首页效果
- AS3 Worker DEMO
- 微信开发-access_token 过期解决方法
- jquery easyui datagrid分页显示数据
- 混合运算(控制台)
- 80后的程序员,你们存了多少钱,买房还差多少?
- MyEclipse设置Java代码注释模板
- 一步一步理解Paxos算法
- Ubuntu 14.10 安装与 VMWare 版本选择
- 利用栈实现进制转换1,常用进制转换成十进制
- Spark修炼之道(进阶篇)——Spark入门到精通:第四节 Spark编程模型(一)
- 家和万事兴——h5专题页
- 二进制文件读写 版本 存在意义 流的含义
- HDU OJ1060Leftmost Digit
- 【Java相关】Java的Object类
- JQuery Easy Ui dataGrid 数据表格
- 手脱EZIP v1.0
- SQL基础语句