HDU—1880


中文题目题意就不多说了

双hashAC代码

get1()得到的是第一重哈希,get2()得到的是第二重哈希,我们用双重哈希来得到精确的哈希值答案。
注意map的用法。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxn=1e5+7;
const int Hash_1=131,Hash_2=233;
int T;
map<pair<int ,int>,string>mp;
char is[300];
char a[110],b[110];
void init()
{mp.clear();
}
int get1(char *s)
{int ans=0;for(int i=0;s[i];i++)ans=(ans*Hash_1%maxn+s[i])%maxn;return ans;
}
int get2(char *s)
{int ans=0;for(int i=0;s[i];i++)ans=(ans*Hash_2%maxn+s[i])%maxn;return ans;
}
int main()
{init();while(gets(is)&&is[0]!='@'){int len=(int)strlen(is);int i=1,j=0,tmp1=0,tmp2=0,tmp3=0,tmp4=0;for(i=1;is[i]!=']';i++)a[i-1]=is[i];a[i-1]=0;tmp1=get1(a);tmp2=get2(a);i+=2;for(j=i;j<len;j++)b[j-i]=is[j];b[j-i]=0;tmp3=get1(b);tmp4=get2(b);mp[make_pair(tmp1,tmp2)]=b;mp[make_pair(tmp3,tmp4)]=a;}scanf("%d",&T);getchar();while(T--){gets(is);if(is[0]=='['){int len=(int)strlen(is);is[len-1]=0;int tmp1=0,tmp2=0;tmp1=get1(is+1);tmp2=get2(is+1);if(mp.find(make_pair(tmp1,tmp2))!=mp.end())cout<<mp[make_pair(tmp1,tmp2)]<<endl;elsecout<<"what?"<<endl;}else{int len=(int)strlen(is);is[len]=0;int tmp1=0,tmp2=0;tmp1=get1(is);tmp2=get2(is);if(mp.find(make_pair(tmp1,tmp2))!=mp.end())cout<<mp[make_pair(tmp1,tmp2)]<<endl;elsecout<<"what?"<<endl;}}return 0;
}
/*_ooOoo_o8888888o88" . "88(| -_- |)O\  =  /O____/`---'\____.'  \\|     |//  `./  \\|||  :  |||//  \/  _||||| -:- |||||-  \|   | \\\  -  /// |   || \_|  ''\---/''  |   |\  .-\__  `-`  ___/-. /___`. .'  /--.--\  `. . __."" '<  `.___\_<|>_/___.'  >'"".| | :  `- \`.;`\ _ /`;.`/ - ` : | |\  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^The program have no BUG.
*/

Hash+二分

现在我们定义两个结构体数组,保存字符串转换后的值,和对应编号。我们提前将“魔咒”和“对应功能”的hash值算出来然后保存下来,然后按hash值从小到大排序,然后后面输入需要查找的,直接去对应数组二分查找就好了,思想很好理解,注意:要是输入的对应功能,要求输出魔咒时,没有那个中括号,细节看代码。

#include <iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<stack>
#include<string>
const int maxn=1e5+10;
const int mod=1e9+7;
const int inf=1e8;
#define me(a,b) memset(a,b,sizeof(a))
#define lowbit(x) x&(-x)
#define mid l+(r-l)/2
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI 3.14159265358979323846
int dir[4][2]= {0,-1,-1,0,0,1,1,0};
typedef long long ll;
using namespace std;
char str1[maxn][30],str2[maxn][100];
int len=0;
struct node
{int has,i;bool friend operator<(node a,node b){return a.has<b.has;}
}cnt1[maxn],cnt2[maxn];///cnt1保存魔咒的hash值,cnt2保存对应功能的hash值
int gethash(char *str)///算一个字符串的hash值
{int sum=0,seed=131;int l=strlen(str);for(int i=0;i<l;i++)sum=sum*seed+str[i];return sum;
}
void solve()///将魔咒和对应功能的字符串转化成相应的hash值
{for(int i=0;i<len;i++){cnt1[i].has=gethash(str1[i]);cnt2[i].has=gethash(str2[i]);cnt1[i].i=cnt2[i].i=i;}sort(cnt1,cnt1+len);///排序,方便后面二分查找。sort(cnt2,cnt2+len);
}
int main()
{while(scanf("%s",str1[len])&&strcmp(str1[len],"@END@")){getchar();gets(str2[len++]);}solve();int n;scanf("%d",&n);getchar();for(int i=0;i<n;i++){char str[105];gets(str);node temp;if(str[0]=='['){temp.has=gethash(str);int pos=lower_bound(cnt1,cnt1+len,temp)-cnt1;///输入的魔咒,在对应数组里面找if(temp.has==cnt1[pos].has)printf("%s\n",str2[cnt1[pos].i]);///若有这个魔咒,输出对应的功能elseprintf("what?\n");}else{temp.has=gethash(str);int pos=lower_bound(cnt2,cnt2+len,temp)-cnt2;///跟上面原理一样if(temp.has==cnt2[pos].has){int len=strlen(str1[cnt2[pos].i]);str1[cnt2[pos].i][len-1]='\0';///这步和下面的+1都是为了不输出那个中括号printf("%s\n",str1[cnt2[pos].i]+1);}elseprintf("what?\n");}}return 0;
}
/*_ooOoo_o8888888o88" . "88(| -_- |)O\  =  /O____/`---'\____.'  \\|     |//  `./  \\|||  :  |||//  \/  _||||| -:- |||||-  \|   | \\\  -  /// |   || \_|  ''\---/''  |   |\  .-\__  `-`  ___/-. /___`. .'  /--.--\  `. . __."" '<  `.___\_<|>_/___.'  >'"".| | :  `- \`.;`\ _ /`;.`/ - ` : | |\  \ `-.   \_ __\ /__ _/   .-` /  /
======`-.____`-.___\_____/___.-`____.-'======`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^The program have no BUG.
*/

大佬代码:

#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long#define  LL long long
const int maxn=1000010;
ull base =131;ull g[maxn];
map<ull , char *> mp;
char T[200];ull Hash(char s[])
{int len=strlen(s);ull ans=0;g[0]=s[0];for(int i=1;i<len;i++){g[i]=g[i-1]*base+s[i];}return g[len-1];
}int main()
{while(1){fgets(T,200,stdin);if(T[0]=='@'){break;}int n=strlen(T), k=1, cut=0;char s[25]={0}, t[85]={0};for(int i=1;i<n-1;i++){if(T[i]==']'){i++;k=2;continue;}if(k==1){s[i-1]=T[i];}if(k==2){t[cut++]=T[i];}}char *p1=new char [25];char *p2=new char [85];strcpy(p1, s);strcpy(p2, t);mp[Hash(s)]= p2, mp[Hash(t)]= p1;}int n;scanf("%d%*c",&n);while(n--){fgets(T,200,stdin);char s[200]={0};int len=strlen(T), cut=0;for(int i=0;i<len-1;i++){if(T[i]!='['&&T[i]!=']'){s[cut++]=T[i];}}ull k=Hash(s);if(mp[k]!=0){printf("%s\n",mp[k]);}else{printf("what?\n");}}return 0;
}

D - 魔咒词典 HDU—1880(双Hash值和map||Hash+二分)相关推荐

  1. hdu 1880 魔咒词典

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  2. 『杭电1880』魔咒词典

    Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔 ...

  3. 杭电acm 1880魔咒词典(水题)

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submi ...

  4. 魔咒词典---哈希+二分

    题目: 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. 给你一 ...

  5. 字符串哈希(魔咒词典hdu1880)

    魔咒词典(字符串哈希) 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你 ...

  6. HDU1880 魔咒词典【文本处理】

    魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  7. ccf练习-魔咒词典(字符串分割,<map>存储)

    [问题描述] 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. ...

  8. 魔咒词典(C/C++)

    题目描述 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助.    ...

  9. 湖南大学21夏训练三3.魔咒词典

    [问题描述] 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. ...

  10. C++映射——魔咒词典

    题目描述 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助.    ...

最新文章

  1. 物联网时代传感器厂商竞争格局揭秘
  2. python能做高频交易吗_python金融高频交易Python ord()是什么?ord()有什么用?
  3. Lambdas中的例外:有点混乱的优雅解决方案
  4. 怎样去理解@ComponentScan注解
  5. 三维重构 c++_桐柏3d打印模型生产厂家【博通三维】-博通三维
  6. web前端基础知识:html布局如何应用?
  7. 安卓加密软件_(安卓)微信聊天加密软件
  8. ssis 表达式任务_SSIS表达式任务与将变量作为表达式求值
  9. 零基础学python好学吗-想要0基础学python要怎么做?python好学吗?
  10. python有道-Python爬去有道翻译
  11. android 模板设计,Android的设计模式-模板方法模式
  12. oracle 建表id自增长_oracle建表设置主键自增
  13. SecureCRT 终端仿真程序 v7.0.0.326 中文绿色便携破解版
  14. ftp 报错 550 Failed to open file
  15. Qt制作简易电子相册
  16. ic 主动均衡_分享几种锂电池均衡电路的工作原理
  17. html 滑动刻度尺,js实现移动端H5页面手指滑动刻度尺功能
  18. Mac IntelliJIDEA非正常关闭解决(reopen失败)
  19. 【C++】模板进阶 — 模板特化
  20. php css属性,php学习之css常用的属性(三)

热门文章

  1. 高分辨透射电镜(HRTEM)样品怎么制?看这一篇就够了
  2. 论文写作:如何写论文
  3. 写论文的公式怎么写最便捷?
  4. 高琪飞机项目飞机爆炸图片_爆炸式的工作机会和多项目同步
  5. 永恒之蓝--Windows server 2003R2
  6. windows server 2003忘记密码
  7. 台式机鼠标失灵打开计算机,终于懂了台式电脑鼠标键盘不能用怎么办了
  8. html 跑步比赛小游戏,小班游戏教案:跑步比赛
  9. 笔记本java稳定wifi信号_笔记本wifi网速不稳定的解决方法
  10. NCPC2015 A Adjoin the Networks(求树的直径)