rt,若干年前用 STL 切掉了本题,一直以为本题很水,直到今天正式学哈希才发现有点玄学。
现在有两份代码。一份没有将输入以字符串的形式存储起来,而是使用 getchar()
一个字符一个字符地读入并计算哈希值;另一份就是传统的思路,老老实实读入字符串,传参给 hashh
函数来计算哈希值。除此以外,两种做法别无二致。
某种意义上来讲,前者更优,因为它只用了一个字符,空间、时间开销更小;但事实上,它无法通过,而且下载测试点后本地运行,发现答案并未出错。后者能够通过,但慢得多。
贴上两份代码。这是前一种做法的:
#include<iostream>
#include<string>
#include<algorithm>
#define ull unsigned long long
#define p 212370440130137957ll
using namespace std;
namespace OIfast{
inline int read(){
int n=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9')n=(n*10+c-'0')%p,c=getchar();
return n*f;
}
inline void print(int n){
if(n<0)putchar('-'),n=-n;
if(n>=10)print(n/10);
putchar(n%10+'0');
return ;
}
inline void write(int n,char c){
print(n),putchar(c);
return ;
}
}using namespace OIfast;
const int N=1e7+5;
int n,ans=1;
ull a[N];
signed main(){
n=read();
for(int i=1;i<=n;++i){
ull hash=0;
char c=getchar();
while(c!=' '&&c!='\n'){
hash=(hash*191+(ull)c)%p;
c=getchar();
}
a[i]=hash;
}
sort(a+1,a+n+1);
for(int i=2;i<=n;++i)if(a[i]!=a[i-1])++ans;
write(ans,'\n');
return 0;
}
这是后一种做法的:
#include<iostream>
#include<string>
#include<algorithm>
#define ull unsigned long long
#define p 212370440130137957ll
using namespace std;
namespace OIfast{
inline int read(){
int n=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9')n=(n*10+c-'0')%p,c=getchar();
return n*f;
}
inline void print(int n){
if(n<0)putchar('-'),n=-n;
if(n>=10)print(n/10);
putchar(n%10+'0');
return ;
}
inline void write(int n,char c){
print(n),putchar(c);
return ;
}
}using namespace OIfast;
const int N=1e7+5;
int n,ans=1;
ull a[N];
inline ull hashh(string s){
int l=s.size();
ull x=0;
for(int i=0;i<l;++i){
x=(x*191+(ull)s[i])%p;
}
return x;
}
signed main(){
n=read();
for(int i=1;i<=n;++i){
string s;
cin>>s;
a[i]=hashh(s);
}
sort(a+1,a+n+1);
for(int i=2;i<=n;++i)if(a[i]!=a[i-1])++ans;
write(ans,'\n');
return 0;
}
就这 B 板子折腾我一早上了,旁边同学都切了几道蓝了而我还在研究这道橙,非常红温。