loj.ac 10034
方法1:存储为哈希表,再查询,100%可靠,可处理hash冲突。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int mod1=1e6+3, mod2=1e6+9, p1=47, p2=79, N=30010;
int tot=0, nxt[N], poi[mod1+10], end[N];
void insert(int x, int y) //类似链式前向星的存储方式
{
nxt[++tot]=poi[x];
poi[x]=tot;
end[tot]=y;
}
bool query(int x, int y)
{
for(int i=poi[x]; i; i=nxt[i])
if(end[i]==y) return true;
return false;
}
int main()
{
int n;
char op[10], s[210];
scanf("%d", &n);
while(n--)
{
scanf("%s", op); //读入到空格
gets(s); //读入剩余的一整行
int len=strlen(s), sum1=0, sum2=0;
for(int i=0; i<len; i++)
{ //双哈希,减小误差
sum1=(sum1*p1+s[i])%mod1; //直接使用字符的ASCII值
sum2=(sum2*p2+s[i])%mod2;
}
if(op[0]=='a') insert(sum1, sum2);
else
{
if(query(sum1, sum2)) printf("yes
");
else printf("no
");
}
}
return 0;
}
方法2:字符串哈希,有hash冲突的几率,取决于数据的强弱。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<string>
using namespace std;
typedef unsigned long long ull;
set<ull> S;
int main()
{
int n;
string op, s;
scanf("%d", &n);
while(n--)
{
cin>>op; //读入到空格
getline(cin, s); //读入剩余的一整行
ull sum1=0;
for(int i=0; i<s.length(); i++)
sum1=sum1*133+s[i]; //直接使用字符的ASCII值,自然溢出
if(op[0]=='a') S.insert(sum1);
else
{
if(S.find(sum1)!=S.end()) printf("yes
");
else printf("no
");
}
}
return 0;
}