题目描述

如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字、大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串。

友情提醒:如果真的想好好练习哈希的话,请自觉,否则请右转PJ试炼场:)

输入输出格式

输入格式:

第一行包含一个整数N,为字符串的个数。

接下来N行每行包含一个字符串,为所提供的字符串。

输出格式:

输出包含一行,包含一个整数,为不同的字符串个数。

输入输出样例

输入样例#1:

5
abc
aaaa
abc
abcc
12345
输出样例#1:

4

说明

时空限制:1000ms,128M

数据规模:

对于30%的数据:N<=10,Mi≈6,Mmax<=15;

对于70%的数据:N<=1000,Mi≈100,Mmax<=150

对于100%的数据:N<=10000,Mi≈1000,Mmax<=1500

样例说明:

样例中第一个字符串(abc)和第三个字符串(abc)是一样的,所以所提供字符串的集合为{aaaa,abc,abcc,12345},故共计4个不同的字符串。

Tip: 感兴趣的话,你们可以先看一看以下三题:

BZOJ3097:http://www.lydsy.com/JudgeOnline/problem.php?id=3097

BZOJ3098:http://www.lydsy.com/JudgeOnline/problem.php?id=3098

BZOJ3099:http://www.lydsy.com/JudgeOnline/problem.php?id=3099

如果你仔细研究过了(或者至少仔细看过AC人数的话),我想你一定会明白字符串哈希的正确姿势的^_^

字符串hash,把每一位当做一个某进制大数的一位,乘积后mod一个素数

在此讲解三种姿势

1.ull自然溢出

100分

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
typedef unsigned long long ull;
int hash[maxn];
int base=;
char s[maxn]; int n,ans=;
ull h(char *s) {
int len =strlen(s);
ull ans=;
for(int i=;i<len;++i)
ans=ans*(ull)base+(ull)s[i];
return ans&0x7fffffff;
}
int main () {
scanf("%d",&n);
for(int i=;i<=n;++i) {
scanf("%s",s);
hash[i]=h(s);
}
sort(hash+,hash+n+);
for(int i=;i<=n;++i)
if(hash[i]!=hash[i-])
ans++;
printf("%d\n",ans);
return ;
}

2.对单素数取mod

70分

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
typedef unsigned long long ull;
ull mod = ;
int hash[maxn];
int base=;
char s[maxn]; int n,ans=;
ull h(char *s) {
int len =strlen(s);
ull ans=;
for(int i=;i<len;++i)
ans=(ans*(ull)base+(ull)s[i])%mod;
return ans;
}
int main () {
scanf("%d",&n);
for(int i=;i<=n;++i) {
scanf("%s",s);
hash[i]=h(s);
}
sort(hash+,hash+n+);
for(int i=;i<=n;++i)
if(hash[i]!=hash[i-])
ans++;
printf("%d\n",ans);
return ;
}

对双素数取mod

100分

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = ;
typedef unsigned long long ull;
const int mod1 = ;
const int mod2 = ;
struct data{
int x, y;
bool operator < (const data &a)const {
return x< a.x;
}
}hash[maxn];
int base=;
char s[maxn]; int n,ans=;
int h1(char *s) {
int len =strlen(s);
int ans=;
for(int i=;i<len;++i)
ans=(ans*base+s[i])%mod1;
return ans;
}
int h2(char *s) {
int len =strlen (s);
int ans=;
for(int i=;i<len;++i)
ans=(ans*base+s[i])%mod2;
return ans;
}
int main () {
scanf("%d",&n);
for(int i=;i<=n;++i) {
scanf("%s",s);
hash[i].x=h1(s);
hash[i].y=h2(s);
}
sort(hash+,hash+n+);
for(int i=;i<=n;++i)
if(hash[i].x!=hash[i-].x||hash[i].y!=hash[i-].y)
ans++;
printf("%d\n",ans);
return ;
}

最新文章

  1. java Future 接口介绍
  2. php环境的搭建
  3. 【BZOJ-2730】矿场搭建 Tarjan 双连通分量
  4. 351. Android Unlock Patterns
  5. QT5-控件-QFontComboBox-字体选择下拉列表,使用一个标签查看效果
  6. Appium Android Bootstrap控制源代码的分析AndroidElement
  7. error: C2664: “zajiao::zajiao(const zajiao &amp;)”: 无法将参数 1 从“const char [12]”转换为“char *”
  8. Android 动画animation 深入分析
  9. Android------&gt;TableLayout表格布局方式
  10. 【论文:麦克风阵列增强】An alternative approach to linearly constrained adaptive beamforming
  11. VxWorks中的中断应用设计要点
  12. 2016 苹果全球开发者大会(WWDC)
  13. vs2010下使用sqlite
  14. hadoop的hdfs中的javaAPI操作
  15. Python基础【day02】:字符编码(一)
  16. window.open子窗口获取父窗口的值
  17. 《F4+2—团队项目设计完善&amp;编码测试》
  18. Windows环境下用jwplayer+Nginx搭建视频点播服务器
  19. SVN中Revert changes from this revision 跟Revert to this revision
  20. jQuery中animate与scrollTop、offset().top实例

热门文章

  1. Lucene原理与代码分析
  2. 计算机应用第七次作业 html制作个人音乐播放站点
  3. EAGLView介绍
  4. 【倍增】7.11fusion
  5. mysql 审核引擎 goInception 的基本使用
  6. Makefile文件中的sed介绍
  7. 对linux中source,fork,exec的理解以及case的 使用
  8. Makefile学习(一)----初步理解
  9. MFC中Picture控件显示图像
  10. linux查找和替换命令