D - 魔咒词典 HDU—1880(双Hash值和map||Hash+二分)
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+二分)相关推荐
- hdu 1880 魔咒词典
魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 『杭电1880』魔咒词典
Problem Description 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔 ...
- 杭电acm 1880魔咒词典(水题)
魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- 魔咒词典---哈希+二分
题目: 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. 给你一 ...
- 字符串哈希(魔咒词典hdu1880)
魔咒词典(字符串哈希) 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你 ...
- HDU1880 魔咒词典【文本处理】
魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- ccf练习-魔咒词典(字符串分割,<map>存储)
[问题描述] 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. ...
- 魔咒词典(C/C++)
题目描述 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. ...
- 湖南大学21夏训练三3.魔咒词典
[问题描述] 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. ...
- C++映射——魔咒词典
题目描述 哈利波特在魔法学校的必修课之一就是学习魔咒.据说魔法世界有100000种不同的魔咒,哈利很难全部记住,但是为了对抗强敌,他必须在危急时刻能够调用任何一个需要的魔咒,所以他需要你的帮助. ...
最新文章
- 物联网时代传感器厂商竞争格局揭秘
- python能做高频交易吗_python金融高频交易Python ord()是什么?ord()有什么用?
- Lambdas中的例外:有点混乱的优雅解决方案
- 怎样去理解@ComponentScan注解
- 三维重构 c++_桐柏3d打印模型生产厂家【博通三维】-博通三维
- web前端基础知识:html布局如何应用?
- 安卓加密软件_(安卓)微信聊天加密软件
- ssis 表达式任务_SSIS表达式任务与将变量作为表达式求值
- 零基础学python好学吗-想要0基础学python要怎么做?python好学吗?
- python有道-Python爬去有道翻译
- android 模板设计,Android的设计模式-模板方法模式
- oracle 建表id自增长_oracle建表设置主键自增
- SecureCRT 终端仿真程序 v7.0.0.326 中文绿色便携破解版
- ftp 报错 550 Failed to open file
- Qt制作简易电子相册
- ic 主动均衡_分享几种锂电池均衡电路的工作原理
- html 滑动刻度尺,js实现移动端H5页面手指滑动刻度尺功能
- Mac IntelliJIDEA非正常关闭解决(reopen失败)
- 【C++】模板进阶 — 模板特化
- php css属性,php学习之css常用的属性(三)